diff --git a/CHANGES b/CHANGES index bec290fb..b5d5f806 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +Refresh 16.5 (Another two years later...) + +1.) Fix build with make-4.4. (#1218) +2.) Split src/audio/ into separate directories per version (#1219) +3.) Remove unused string defines for PAL (#1216) +4.) Update armips.cpp (#1217) +5.) Libultra and OS related assembly cleanup, compiler improvements and more (#1210) + Refresh 16 (Two years later...) 1.) remove capstone from readme, slight update (#1212) 2.) Update ido static recomp (#1211) diff --git a/Makefile b/Makefile index b267233e..6e426ca6 100644 --- a/Makefile +++ b/Makefile @@ -40,32 +40,32 @@ ifeq ($(VERSION),jp) DEFINES += VERSION_JP=1 OPT_FLAGS := -g GRUCODE ?= f3d_old - VERSION_JP_US ?= true - VERSION_SH_CN ?= false + LIBULTRA ?= D + AUDIO_SRC_DIR ?= src/audio/us_jp else ifeq ($(VERSION),us) DEFINES += VERSION_US=1 OPT_FLAGS := -g GRUCODE ?= f3d_old - VERSION_JP_US ?= true - VERSION_SH_CN ?= false + LIBULTRA ?= D + AUDIO_SRC_DIR ?= src/audio/us_jp else ifeq ($(VERSION),eu) DEFINES += VERSION_EU=1 OPT_FLAGS := -O2 GRUCODE ?= f3d_new - VERSION_JP_US ?= false - VERSION_SH_CN ?= false + LIBULTRA ?= F + AUDIO_SRC_DIR ?= src/audio/eu else ifeq ($(VERSION),sh) DEFINES += VERSION_SH=1 OPT_FLAGS := -O2 GRUCODE ?= f3d_new - VERSION_JP_US ?= false - VERSION_SH_CN ?= true + LIBULTRA ?= H + AUDIO_SRC_DIR ?= src/audio/sh else ifeq ($(VERSION),cn) DEFINES += VERSION_CN=1 OPT_FLAGS := -O2 GRUCODE ?= f3d_new - VERSION_JP_US ?= false - VERSION_SH_CN ?= true + LIBULTRA ?= BB + AUDIO_SRC_DIR ?= src/audio/sh endif TARGET := sm64.$(VERSION) @@ -92,7 +92,6 @@ else ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.0J / Animal Forest - Dōbutsu no Mo DEFINES += F3DZEX_GBI_2=1 F3DEX_GBI_2=1 F3DEX_GBI_SHARED=1 endif - # USE_QEMU_IRIX - when ido is selected, select which way to emulate IRIX programs # 1 - use qemu-irix # 0 - statically recompile the IRIX programs @@ -174,6 +173,10 @@ endif DEFINES += _FINALROM=1 +ifeq ($(TARGET_N64),1) + DEFINES += TARGET_N64=1 +endif + #==============================================================================# # Universal Dependencies # #==============================================================================# @@ -212,7 +215,6 @@ ifeq ($(filter clean distclean print-%,$(MAKECMDGOALS)),) endif - #==============================================================================# # Target Executable and Sources # #==============================================================================# @@ -222,7 +224,6 @@ BUILD_DIR_BASE := build BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION) ROM := $(BUILD_DIR)/$(TARGET).z64 ELF := $(BUILD_DIR)/$(TARGET).elf -LIBULTRA := $(BUILD_DIR)/libultra.a LD_SCRIPT := sm64.ld CHARMAP := charmap.txt CHARMAP_DEBUG := charmap.debug.txt @@ -233,16 +234,13 @@ ACTOR_DIR := actors LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h))) # Directories containing source files -SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets asm lib sound +SRC_DIRS := src src/engine src/game src/menu src/buffers src/audio $(AUDIO_SRC_DIR) actors levels bin data assets asm lib sound BIN_DIRS := bin bin/$(VERSION) ifeq ($(VERSION),cn) LIBGCC_SRC_DIRS += lib/src/libgcc endif -ULTRA_SRC_DIRS := lib/src lib/src/math lib/asm lib/data -ULTRA_BIN_DIRS := lib/bin - GODDARD_SRC_DIRS := src/goddard src/goddard/dynlists # File dependencies and variables for specific files @@ -252,9 +250,7 @@ include Makefile.split LEVEL_C_FILES := $(wildcard levels/*/leveldata.c) $(wildcard levels/*/script.c) $(wildcard levels/*/geo.c) C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) $(LEVEL_C_FILES) S_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.s)) -ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c)) GODDARD_C_FILES := $(foreach dir,$(GODDARD_SRC_DIRS),$(wildcard $(dir)/*.c)) -ULTRA_S_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.s)) LIBGCC_C_FILES := $(foreach dir,$(LIBGCC_SRC_DIRS),$(wildcard $(dir)/*.c)) GENERATED_C_FILES := $(BUILD_DIR)/assets/mario_anim_data.c $(BUILD_DIR)/assets/demo_data.c @@ -281,21 +277,18 @@ O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \ $(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \ $(foreach file,$(GENERATED_C_FILES),$(file:.c=.o)) -ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \ - $(foreach file,$(ULTRA_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) - GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) LIBGCC_O_FILES := $(foreach file,$(LIBGCC_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) # Automatic dependency files -DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(LIBGCC_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d +DEP_FILES := $(O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(LIBGCC_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d # Files with GLOBAL_ASM blocks ifeq ($(NON_MATCHING),0) GLOBAL_ASM_C_FILES != grep -rl 'GLOBAL_ASM(' $(wildcard src/**/*.c) -GLOBAL_ASM_O_FILES = $(foreach file,$(GLOBAL_ASM_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) -GLOBAL_ASM_DEP = $(BUILD_DIR)/src/audio/non_matching_dep + GLOBAL_ASM_O_FILES = $(foreach file,$(GLOBAL_ASM_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) + GLOBAL_ASM_DEP = $(BUILD_DIR)/src/audio/non_matching_dep endif @@ -303,8 +296,8 @@ endif # Compiler Options # #==============================================================================# -IQUE_EGCS_PATH := $(TOOLS_DIR)/ique_egcs -IQUE_LD_PATH := $(TOOLS_DIR)/ique_ld +EGCS_PATH := $(TOOLS_DIR)/egcs +LD_PATH := $(TOOLS_DIR)/ld # detect prefix for MIPS toolchain ifneq ($(call find-command,mips-linux-gnu-ld),) @@ -333,63 +326,61 @@ else COPT := $(IDO_ROOT)/copt endif endif -ifeq ($(VERSION),cn) - LD := LD_LIBRARY_PATH=$(IQUE_LD_PATH) $(IQUE_LD_PATH)/mips64-elf-ld -else +ifeq ($(COMPILER),gcc) LD := $(CROSS)ld +else + LD := LD_LIBRARY_PATH=$(LD_PATH) $(LD_PATH)/mips64-elf-ld endif AR := $(CROSS)ar OBJDUMP := $(CROSS)objdump OBJCOPY := $(CROSS)objcopy ifeq ($(TARGET_N64),1) - TARGET_CFLAGS := -nostdinc -DTARGET_N64 -D_LANGUAGE_C + TARGET_CFLAGS := -nostdinc -D_LANGUAGE_C CC_CFLAGS := -fno-builtin endif INCLUDE_DIRS := include $(BUILD_DIR) $(BUILD_DIR)/include src . ifeq ($(TARGET_N64),1) - INCLUDE_DIRS += include/libc + INCLUDE_DIRS += include/gcc endif C_DEFINES := $(foreach d,$(DEFINES),-D$(d)) DEF_INC_CFLAGS := $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(C_DEFINES) -IQUE_AS := $(IQUE_EGCS_PATH)/as -IQUE_ASFLAGS = -mcpu=r4300 -mabi=32 $(MIPSISET) $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(foreach d,$(DEFINES),--defsym $(d)) +EGCS_AS := $(EGCS_PATH)/as +EGCS_ASFLAGS = -mcpu=r4300 -mabi=32 $(foreach i,$(INCLUDE_DIRS),-I$(i)) + +include libultra.mk ifeq ($(VERSION),cn) - IQUE_REASSEMBLED_ASM_FILES := $(wildcard asm/*.s) $(wildcard lib/asm/*.s) - IQUE_REASSEMBLED_ASM_FILES := $(filter-out asm/ipl3_font.s,$(IQUE_REASSEMBLED_ASM_FILES)) - IQUE_REASSEMBLED := $(foreach file,$(IQUE_REASSEMBLED_ASM_FILES),$(BUILD_DIR)/$(file:.s=.o)) - $(IQUE_REASSEMBLED): AS := $(IQUE_AS) - $(IQUE_REASSEMBLED): MIPSISET := - $(IQUE_REASSEMBLED): ASFLAGS = $(IQUE_ASFLAGS) + EGCS_REASSEMBLED_ASM_FILES := $(wildcard asm/*.s) + EGCS_REASSEMBLED_ASM_FILES := $(filter-out asm/ipl3_font.s, $(EGCS_REASSEMBLED_ASM_FILES)) + EGCS_REASSEMBLED := $(foreach file,$(EGCS_REASSEMBLED_ASM_FILES),$(BUILD_DIR)/$(file:.s=.o)) + $(EGCS_REASSEMBLED): AS := $(EGCS_AS) + $(EGCS_REASSEMBLED): ASFLAGS = $(EGCS_ASFLAGS) endif -IQUE_CC := COMPILER_PATH=$(IQUE_EGCS_PATH) $(IQUE_EGCS_PATH)/gcc -IQUE_CFLAGS = -G 0 $(TARGET_CFLAGS) $(OPT_FLAGS) -D__sgi -DBBPLAYER -mcpu=r4300 -mgp32 -fno-pic -Wa,--strip-local-absolute $(MIPSISET) $(DEF_INC_CFLAGS) +EGCS_CC := COMPILER_PATH=$(EGCS_PATH) $(EGCS_PATH)/gcc +EGCS_CFLAGS = -G 0 $(TARGET_CFLAGS) -mcpu=r4300 -fno-pic -Wa,--strip-local-absolute $(DEF_INC_CFLAGS) # iQue recompiled some files with a different compiler ifeq ($(VERSION),cn) IQUE_RECOMPILED_SRC_GAME := $(addprefix $(BUILD_DIR)/src/game/,rumble_init.o level_update.o memory.o area.o print.o ingame_menu.o hud.o cn_common_syms_1.o cn_common_syms_2.o) $(addprefix $(BUILD_DIR)/src/menu/,title_screen.o intro_geo.o file_select.o star_select.o) - IQUE_RECOMPILED_LIB_SRC := $(ULTRA_O_FILES) - # osDriveRomInit is weird - IQUE_RECOMPILED_LIB_SRC := $(filter-out $(addprefix $(BUILD_DIR)/lib/src/,osDriveRomInit.o),$(IQUE_RECOMPILED_LIB_SRC)) IQUE_RECOMPILED_LIBGCC_SRC := $(LIBGCC_O_FILES) - IQUE_RECOMPILED = $(IQUE_RECOMPILED_SRC_GAME) $(IQUE_RECOMPILED_LIB_SRC) $(IQUE_RECOMPILED_LIBGCC_SRC) - $(IQUE_RECOMPILED): CC := $(IQUE_CC) + IQUE_RECOMPILED = $(IQUE_RECOMPILED_SRC_GAME) $(IQUE_RECOMPILED_LIBGCC_SRC) + $(IQUE_RECOMPILED): CC := $(EGCS_CC) + $(IQUE_RECOMPILED): CFLAGS = $(EGCS_CFLAGS) $(IQUE_RECOMPILED): MIPSISET := - $(IQUE_RECOMPILED): CFLAGS = $(IQUE_CFLAGS) endif # Prefer clang as C preprocessor if installed on the system ifneq (,$(call find-command,clang)) CPP := clang - CPPFLAGS := -E -P -x c -Wno-trigraphs -D_LANGUAGE_ASSEMBLY $(DEF_INC_CFLAGS) + CPPFLAGS := -E -P -x c -Wno-trigraphs $(DEF_INC_CFLAGS) else CPP := cpp - CPPFLAGS := -P -Wno-trigraphs -D_LANGUAGE_ASSEMBLY $(DEF_INC_CFLAGS) + CPPFLAGS := -P -Wno-trigraphs $(DEF_INC_CFLAGS) endif # Check code syntax with host compiler @@ -397,14 +388,14 @@ CC_CHECK := gcc CC_CHECK_CFLAGS := -fsyntax-only -fsigned-char $(CC_CFLAGS) $(TARGET_CFLAGS) -std=gnu90 -Wall -Wextra -Wno-format-security -Wno-main -DNON_MATCHING -DAVOID_UB $(DEF_INC_CFLAGS) # C compiler options -CFLAGS = -G 0 $(OPT_FLAGS) $(TARGET_CFLAGS) $(MIPSISET) $(DEF_INC_CFLAGS) +CFLAGS = -G 0 $(TARGET_CFLAGS) $(DEF_INC_CFLAGS) ifeq ($(COMPILER),gcc) CFLAGS += -mno-shared -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -Wall -Wextra else CFLAGS += -non_shared -Wab,-r4300_mul -Xcpluscomm -Xfullwarn -signed -32 endif -ASFLAGS := -march=vr4300 -mabi=32 $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(foreach d,$(DEFINES),--defsym $(d)) +ASFLAGS := -march=vr4300 -mabi=32 $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(foreach d,$(DEFINES),--defsym $(d)) RSPASMFLAGS := $(foreach d,$(DEFINES),-definelabel $(subst =, ,$(d))) ifeq ($(shell getconf LONG_BIT), 32) @@ -492,8 +483,6 @@ test: $(ROM) load: $(ROM) $(LOADER) $(LOADER_FLAGS) $< -libultra: $(BUILD_DIR)/libultra.a - # Extra object file dependencies $(BUILD_DIR)/asm/ipl3_font.o: $(IPL3_RAW_FILES) $(BUILD_DIR)/src/game/crash_screen.o: $(CRASH_TEXTURE_C_FILES) @@ -501,9 +490,7 @@ $(BUILD_DIR)/lib/rsp.o: $(BUILD_DIR)/rsp/rspboot.bin $(BUILD_DIR)/ $(SOUND_BIN_DIR)/sound_data.o: $(SOUND_BIN_DIR)/sound_data.ctl.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.inc.c $(SOUND_BIN_DIR)/sequences.bin.inc.c $(SOUND_BIN_DIR)/bank_sets.inc.c $(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h -ifeq ($(VERSION_SH_CN),true) - $(BUILD_DIR)/src/audio/load_sh.o: $(SOUND_BIN_DIR)/bank_sets.inc.c $(SOUND_BIN_DIR)/sequences_header.inc.c $(SOUND_BIN_DIR)/ctl_header.inc.c $(SOUND_BIN_DIR)/tbl_header.inc.c -endif +$(BUILD_DIR)/src/audio/sh/load.o: $(SOUND_BIN_DIR)/bank_sets.inc.c $(SOUND_BIN_DIR)/sequences_header.inc.c $(SOUND_BIN_DIR)/ctl_header.inc.c $(SOUND_BIN_DIR)/tbl_header.inc.c $(CRASH_TEXTURE_C_FILES): TEXTURE_ENCODING := u32 @@ -535,7 +522,7 @@ else endif $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/debug_text.raw.inc.c -ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_BIN_DIRS) $(LIBGCC_SRC_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) rsp include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) +ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(LIBGCC_SRC_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) rsp include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) # Make sure build directory exists before compiling anything DUMMY != mkdir -p $(ALL_DIRS) @@ -580,9 +567,11 @@ $(BUILD_DIR)/%.ci4: %.ci4.png $(BUILD_DIR)/%.elf: $(BUILD_DIR)/%.o $(call print,Linking ELF file:,$<,$@) $(V)$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map -o $@ $< -# Override for leveldata.elf, which otherwise matches the above pattern +# Override for leveldata.elf, which otherwise matches the above pattern. +# Has to be a static pattern rule for make-4.4 and above to trigger the second +# expansion. .SECONDEXPANSION: -$(BUILD_DIR)/levels/%/leveldata.elf: $(BUILD_DIR)/levels/%/leveldata.o $(BUILD_DIR)/bin/$$(TEXTURE_BIN).elf +$(LEVEL_ELF_FILES): $(BUILD_DIR)/levels/%/leveldata.elf: $(BUILD_DIR)/levels/%/leveldata.o $(BUILD_DIR)/bin/$$(TEXTURE_BIN).elf $(call print,Linking ELF file:,$<,$@) $(V)$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map --just-symbols=$(BUILD_DIR)/bin/$(TEXTURE_BIN).elf -o $@ $< @@ -717,166 +706,66 @@ $(GLOBAL_ASM_DEP).$(NON_MATCHING): # Compilation Recipes # #==============================================================================# -# Compile C code -$(BUILD_DIR)/%.o: %.c - $(call print,Compiling:,$<,$@) - $(V)$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< - $(V)$(CC) -c $(CFLAGS) -o $@ $< -ifeq ($(VERSION),cn) - $(V)$(TOOLS_DIR)/patch_elf_32bit $@ -endif -$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.c - $(call print,Compiling:,$<,$@) - $(V)$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< - $(V)$(CC) -c $(CFLAGS) -o $@ $< -ifeq ($(VERSION),cn) - $(V)$(TOOLS_DIR)/patch_elf_32bit $@ -endif - # Alternate compiler flags needed for matching -ifeq ($(COMPILER),ido) +ifeq ($(NON_MATCHING),0) $(BUILD_DIR)/levels/%/leveldata.o: OPT_FLAGS := -g $(BUILD_DIR)/actors/%.o: OPT_FLAGS := -g $(BUILD_DIR)/bin/%.o: OPT_FLAGS := -g $(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g $(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1 - $(BUILD_DIR)/lib/asm/__osDisableInt.o: MIPSISET := -mips2 - $(BUILD_DIR)/lib/asm/bcopy.o: MIPSISET := -mips2 - $(BUILD_DIR)/lib/src/%.o: OPT_FLAGS := - $(BUILD_DIR)/lib/src/math/%.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/math/ll%.o: OPT_FLAGS := - $(BUILD_DIR)/lib/src/math/ll%.o: MIPSISET := -mips3 -32 - $(BUILD_DIR)/lib/src/ldiv.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/string.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/gu%.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/al%.o: OPT_FLAGS := -O3 - ifeq ($(VERSION_SH_CN),true) - $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/osDriveRomInit.o: OPT_FLAGS := -g - endif ifeq ($(VERSION),cn) - $(BUILD_DIR)/lib/src/osAiSetFrequency.o: MIPSISET := -mips2 - $(BUILD_DIR)/lib/src/osVirtualToPhysical.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osInitializeIQueWrapper.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/osAiGetLength.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/osAiSetFrequency.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/math/cosf.o: OPT_FLAGS := -O2 -mips2 - $(BUILD_DIR)/lib/src/guOrthoF.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/guPerspectiveF.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osAiSetNextBuffer.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osContStartReadData.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osContInit.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/math/sinf.o: OPT_FLAGS := -O2 -mips2 - $(BUILD_DIR)/lib/src/math/ll%.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/string.o: OPT_FLAGS := -O2 -mips2 - $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSyncPrintf.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osCreateMesgQueue.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osRecvMesg.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSendMesg.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSetEventMesg.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSpTaskLoadGo.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSpTaskYield.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSpTaskYielded.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSiRawStartDma.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSiCreateAccessQueue.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osCreateThread.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSetThreadPri.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osStartThread.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osDequeueThread.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osGetCurrFaultedThread.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osGetTime.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSetTime.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osSetTimer.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osTimer.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osCreateViManager.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osViSetEvent.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osViSetMode.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osViSetSpecialFeatures.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osViSwapBuffer.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osViSwapContext.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osViBlack.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/guRotateF.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEepromProbe.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEepromLongWrite.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEepromLongRead.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osCreatePiManager.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEPiRawStartDma.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/epidma.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osCartRomInit.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osDevMgrMain.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osPiCreateAccessQueue.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osPiStartDma.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/motor.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osInitialize.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osAiDeviceBusy.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osJamMesg.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSpDeviceBusy.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSpGetStatus.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSpSetStatus.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSpSetPc.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSpRawStartDma.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSiRawReadIo.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSiRawWriteIo.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osDestroyThread.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osGetThreadPri.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osYieldThread.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osViInit.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osViGetCurrentContext.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEepromRead.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEepromWrite.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSetGlobalIntMask.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osResetGlobalIntMask.o: OPT_FLAGS := -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osPiRawStartDma.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osPiGetCmdQueue.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEPiRawReadIo.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/osEPiRawWriteIo.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/ldiv.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 - $(BUILD_DIR)/lib/src/__osSiDeviceBusy.o: OPT_FLAGS := -O2 -mno-abicalls -mips2 $(BUILD_DIR)/lib/src/libgcc/%.o: OPT_FLAGS := -O2 -g -mips2 endif - ifeq ($(VERSION),eu) - $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3 - # For all audio files other than external.c and port_eu.c, put string literals - # in .data. (In Shindou, the port_eu.c string literals also moved to .data.) - $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -use_readwrite_const - $(BUILD_DIR)/src/audio/port_eu.o: OPT_FLAGS := -O2 - endif - ifeq ($(VERSION_JP_US),true) - $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 - $(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -framepointer - # The source-to-source optimizer copt is enabled for audio. This makes it use - # acpp, which needs -Wp,-+ to handle C++-style comments. - # All other files than external.c should really use copt, but only a few have - # been matched so far. - $(BUILD_DIR)/src/audio/effects.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-inline=sequence_channel_process_sound,-scalaroptimize=1 -Wp,-+ - $(BUILD_DIR)/src/audio/synthesis.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-scalaroptimize=1 -Wp,-+ - endif - $(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 + # Audio specific flags: + + # For EU, all audio files other than external.c and port.c put string literals + # in .data. (In Shindou, the port.c string literals also moved to .data.) + $(BUILD_DIR)/src/audio/eu/%.o: OPT_FLAGS := -O2 -use_readwrite_const + $(BUILD_DIR)/src/audio/eu/port.o: OPT_FLAGS := -O2 + + # US/JP disable loop unrolling and enable -framepointer for one file. + $(BUILD_DIR)/src/audio/us_jp/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 + $(BUILD_DIR)/src/audio/us_jp/load.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -framepointer + + # The source-to-source optimizer copt is enabled for US/JP audio. This makes it use + # acpp, which needs -Wp,-+ to handle C++-style comments. + # All other files than external.c should really use copt, but only a few have + # been matched so far. + $(BUILD_DIR)/src/audio/us_jp/effects.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-inline=sequence_channel_process_sound,-scalaroptimize=1 -Wp,-+ + $(BUILD_DIR)/src/audio/us_jp/synthesis.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-scalaroptimize=1 -Wp,-+ + + $(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 # Add a target for build/eu/src/audio/*.copt to make it easier to see debug $(BUILD_DIR)/src/audio/%.acpp: src/audio/%.c $(ACPP) $(TARGET_CFLAGS) $(DEF_INC_CFLAGS) -D__sgi -+ $< > $@ $(BUILD_DIR)/src/audio/%.copt: $(BUILD_DIR)/src/audio/%.acpp $(COPT) -signed -I=$< -CMP=$@ -cp=i -scalaroptimize=1 $(COPTFLAGS) -$(BUILD_DIR)/src/audio/seqplayer.copt: COPTFLAGS := -inline_manual +$(BUILD_DIR)/src/audio/%/seqplayer.copt: COPTFLAGS := -inline_manual endif +# Compile C code +$(BUILD_DIR)/%.o: %.c + $(call print,Compiling:,$<,$@) + $(V)$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< + $(V)$(CC) -c $(CFLAGS) $(OPT_FLAGS) $(MIPSISET) -o $@ $< +ifeq ($(VERSION),cn) + $(V)$(TOOLS_DIR)/patch_elf_32bit $@ +endif +$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.c + $(call print,Compiling:,$<,$@) + $(V)$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< + $(V)$(CC) -c $(CFLAGS) $(OPT_FLAGS) $(MIPSISET) -o $@ $< +ifeq ($(VERSION),cn) + $(V)$(TOOLS_DIR)/patch_elf_32bit $@ +endif + # Assemble assembly code $(BUILD_DIR)/%.o: %.s $(call print,Assembling:,$<,$@) - $(V)$(CPP) $(CPPFLAGS) $< | $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ + $(V)$(CPP) $(CPPFLAGS) -D_LANGUAGE_ASSEMBLY=1 $< | $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ # Assemble RSP assembly code $(BUILD_DIR)/rsp/%.bin $(BUILD_DIR)/rsp/%_data.bin: rsp/%.s @@ -888,12 +777,6 @@ $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT) $(call print,Preprocessing linker script:,$<,$@) $(V)$(CPP) $(CPPFLAGS) -DBUILD_DIR=$(BUILD_DIR) -MMD -MP -MT $@ -MF $@.d -o $@ $< -# Link libultra -$(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES) - @$(PRINT) "$(GREEN)Linking libultra: $(BLUE)$@ $(NO_COL)\n" - $(V)$(AR) rcs -o $@ $(ULTRA_O_FILES) - $(V)$(TOOLS_DIR)/patch_elf_32bit $@ - # Link libgoddard $(BUILD_DIR)/libgoddard.a: $(GODDARD_O_FILES) @$(PRINT) "$(GREEN)Linking libgoddard: $(BLUE)$@ $(NO_COL)\n" @@ -905,9 +788,9 @@ $(BUILD_DIR)/libgcc.a: $(LIBGCC_O_FILES) $(V)$(AR) rcs -o $@ $(LIBGCC_O_FILES) # Link SM64 ELF file -$(ELF): $(O_FILES) $(MIO0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libultra.a $(BUILD_DIR)/libgoddard.a $(BUILD_DIR)/libgcc.a +$(ELF): $(O_FILES) $(MIO0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) $(LIBULTRA_AR) $(BUILD_DIR)/libgoddard.a $(BUILD_DIR)/libgcc.a @$(PRINT) "$(GREEN)Linking ELF file: $(BLUE)$@ $(NO_COL)\n" - $(V)$(LD) -L $(BUILD_DIR) -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -lultra -lgoddard -lgcc + $(V)$(LD) -L $(BUILD_DIR) -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.$(VERSION).map --no-check-sections $(addprefix -R ,$(SEG_FILES)) -o $@ $(O_FILES) -lultra -lgoddard -lgcc # Build ROM ifeq ($(VERSION),cn) @@ -928,8 +811,6 @@ endif $(BUILD_DIR)/$(TARGET).objdump: $(ELF) $(OBJDUMP) -D $< > $@ - - .PHONY: all clean distclean default diff test load libultra # with no prerequisites, .SECONDARY causes no intermediate target to be removed .SECONDARY: diff --git a/Makefile.split b/Makefile.split index 35ae029c..687ede7b 100644 --- a/Makefile.split +++ b/Makefile.split @@ -39,6 +39,8 @@ ACTOR_GROUPS := \ LEVEL_FILES := $(addsuffix leveldata,$(LEVEL_DIRS)) +LEVEL_ELF_FILES := $(foreach level_dir,$(LEVEL_DIRS),$(BUILD_DIR)/levels/$(level_dir)leveldata.elf) + SEG_FILES := \ $(SEGMENTS:%=$(BUILD_DIR)/bin/%.elf) \ $(ACTOR_GROUPS:%=$(BUILD_DIR)/actors/%.elf) \ diff --git a/asm/boot.s b/asm/boot.s index 381e19ba..bd93ad74 100644 --- a/asm/boot.s +++ b/asm/boot.s @@ -3,12 +3,21 @@ .set noreorder // don't insert nops after branches #include "macros.inc" +#include -.equ EXCEPTION_TLB_MISS, 0x80000000 -.equ SP_DMEM, 0xA4000000 -.equ SP_IMEM, 0xA4001000 -.equ MI_MODE_REG, 0xA4300000 -.equ RI_MODE_REG, 0xA4700000 +#define PHYS_TO_CART(addr) ((addr) | 0xB0000000) +.equ CART_ENTRYPOINT, 0x00000008 +.equ CART_CHECKSUM0, 0x00000010 +.equ CART_CHECKSUM1, 0x00000014 + +// initial DMEM state +.equ SP_DMEM_UNK0, 0x040004C0 +.equ SP_DMEM_UNK1, 0x04000774 + +// This value must fit in one instruction +// - Either use the top 16 bits or the low 16 bits, but not both +.equ INITIAL_DMA_LEN, (0x00100000 - 1) +.equ INITIAL_DMA_ROMPOS, 0x1000 #ifdef VERSION_CN .macro cn_li a b @@ -24,43 +33,42 @@ // 0xA0000000-0xBFFFFFFF: KSEG1 direct map non-cache mirror of 0x00000000 // 0xA4000000-0xA4000FFF: RSP DMEM -// 0xA4000000-0xA400003F: ROM header - .section .text, "ax" // 0xA4000040-0xA4000B6F: IPL3 // IPL3 entry point jumped to from IPL2 glabel ipl3_entry // 0xA4000040 - mtc0 $zero, $13 - mtc0 $zero, $9 - mtc0 $zero, $11 - cn_li $t0, RI_MODE_REG - lw $t1, 0xc($t0) +.ent ipl3_entry + mtc0 $zero, C0_CAUSE + mtc0 $zero, C0_COUNT + mtc0 $zero, C0_COMPARE + cn_li $t0, PHYS_TO_K1(RI_BASE_REG) + lw $t1, %lo(RI_SELECT_REG)($t0) bnez $t1, .LA4000410 - nop + nop addiu $sp, $sp, -0x18 sw $s3, ($sp) sw $s4, 4($sp) sw $s5, 8($sp) sw $s6, 0xc($sp) sw $s7, 0x10($sp) - cn_li $t0, RI_MODE_REG - lui $t2, (0xa3f80000 >> 16) - lui $t3, (0xa3f00000 >> 16) - cn_li $t4, MI_MODE_REG + cn_li $t0, PHYS_TO_K1(RI_BASE_REG) + lui $t2, %hi(PHYS_TO_K1(RDRAM_BASE_REG + 0x80000)) + lui $t3, %hi(PHYS_TO_K1(RDRAM_BASE_REG)) + cn_li $t4, PHYS_TO_K1(MI_BASE_REG) ori $t1, $zero, 64 - sw $t1, 4($t0) + sw $t1, %lo(MI_VERSION_REG)($t0) li $s1, 8000 .LA400009C: nop addi $s1, $s1, -1 bnez $s1, .LA400009C nop - sw $zero, 8($t0) - ori $t1, $zero, 20 - sw $t1, 0xc($t0) - sw $zero, ($t0) + sw $zero, %lo(RI_CURRENT_LOAD_REG)($t0) + ori $t1, $zero, 0x14 + sw $t1, %lo(RI_SELECT_REG)($t0) + sw $zero, %lo(RI_MODE_REG)($t0) li $s1, 4 .LA40000C0: nop @@ -68,34 +76,34 @@ glabel ipl3_entry // 0xA4000040 bnez $s1, .LA40000C0 nop ori $t1, $zero, 14 - sw $t1, ($t0) + sw $t1, %lo(RI_MODE_REG)($t0) li $s1, 32 .LA40000DC: addi $s1, $s1, -1 bnez $s1, .LA40000DC - ori $t1, $zero, 271 - sw $t1, ($t4) + ori $t1, $zero, (MI_SET_INIT | 0xF) + sw $t1, %lo(MI_MODE_REG)($t4) lui $t1, (0x18082838 >> 16) ori $t1, (0x18082838 & 0xFFFF) - sw $t1, 0x8($t2) - sw $zero, 0x14($t2) + sw $t1, %lo(RDRAM_DELAY_REG)($t2) + sw $zero, %lo(RDRAM_REF_ROW_REG)($t2) lui $t1, 0x8000 - sw $t1, 0x4($t2) + sw $t1, %lo(RDRAM_DEVICE_ID_REG)($t2) move $t5, $zero move $t6, $zero - lui $t7, (0xA3F00000 >> 16) + lui $t7, %hi(PHYS_TO_K1(RDRAM_BASE_REG)) move $t8, $zero - lui $t9, (0xA3F00000 >> 16) + lui $t9, %hi(PHYS_TO_K1(RDRAM_BASE_REG)) lui $s6, (0xA0000000 >> 16) move $s7, $zero - lui $a2, (0xA3F00000 >> 16) + lui $a2, %hi(PHYS_TO_K1(RDRAM_BASE_REG)) lui $a3, (0xA0000000 >> 16) move $s2, $zero lui $s4, (0xA0000000 >> 16) addiu $sp, $sp, -0x48 move $fp, $sp - lui $s0, %hi(MI_VERSION_REG) - lw $s0, %lo(MI_VERSION_REG)($s0) + lui $s0, %hi(PHYS_TO_K1(MI_VERSION_REG)) + lw $s0, %lo(PHYS_TO_K1(MI_VERSION_REG))($s0) cn_li $s1, 0x01010101 bne $s0, $s1, .LA4000160 nop @@ -115,14 +123,14 @@ glabel ipl3_entry // 0xA4000040 nop sw $v0, ($sp) li $t1, 8192 - sw $t1, ($t4) - lw $t3, ($t7) + sw $t1, %lo(MI_MODE_REG)($t4) + lw $t3, %lo(RDRAM_CONFIG_REG)($t7) lui $t0, 0xf0ff and $t3, $t3, $t0 sw $t3, 4($sp) addi $sp, $sp, 8 li $t1, 4096 - sw $t1, ($t4) + sw $t1, %lo(MI_MODE_REG)($t4) lui $t0, 0xb019 bne $t3, $t0, .LA40001E0 nop @@ -142,11 +150,11 @@ glabel ipl3_entry // 0xA4000040 add $s4, $s4, $t0 .LA40001E8: li $t0, 8192 - sw $t0, ($t4) - lw $t1, 0x24($t7) - lw $k0, ($t7) + sw $t0, %lo(MI_MODE_REG)($t4) + lw $t1, %lo(RDRAM_DEVICE_MANUF_REG)($t7) + lw $k0, %lo(RDRAM_CONFIG_REG)($t7) li $t0, 4096 - sw $t0, ($t4) + sw $t0, %lo(MI_MODE_REG)($t4) andi $t1, $t1, 0xffff li $t0, 1280 bne $t1, $t0, .LA4000230 @@ -178,9 +186,9 @@ glabel ipl3_entry // 0xA4000040 #else li $t0, 0xc4000000 #endif - sw $t0, 0xc($t2) + sw $t0, %lo(RDRAM_MODE_REG)($t2) li $t0, 0x80000000 - sw $t0, 0x4($t2) + sw $t0, %lo(RDRAM_DEVICE_ID_REG)($t2) move $sp, $fp move $v1, $zero .LA4000274: @@ -248,7 +256,7 @@ glabel ipl3_entry // 0xA4000040 slt $t0, $v1, $t5 bnez $t0, .LA4000274 nop - lui $t2, %hi(RI_REFRESH_REG) + lui $t2, %hi(PHYS_TO_K1(RI_BASE_REG)) sll $s2, $s2, 0x13 lui $t1, (0x00063634 >> 16) ori $t1, (0x00063634 & 0xFFFF) @@ -269,7 +277,7 @@ glabel ipl3_entry // 0xA4000040 lw $s6, 0xc($sp) lw $s7, 0x10($sp) addiu $sp, $sp, 0x18 - cn_li $t0, EXCEPTION_TLB_MISS + cn_li $t0, UT_VEC addiu $t1, $t0, 0x4000 addiu $t1, $t1, -0x20 mtc0 $zero, $28 @@ -279,7 +287,7 @@ glabel ipl3_entry // 0xA4000040 sltu $at, $t0, $t1 bnez $at, .LA40003D8 addiu $t0, $t0, 0x20 - cn_li $t0, EXCEPTION_TLB_MISS + cn_li $t0, UT_VEC addiu $t1, $t0, 0x2000 addiu $t1, $t1, -0x10 .LA40003F8: @@ -290,7 +298,7 @@ glabel ipl3_entry // 0xA4000040 b .LA4000458 nop .LA4000410: - cn_li $t0, EXCEPTION_TLB_MISS + cn_li $t0, UT_VEC addiu $t1, $t0, 0x4000 addiu $t1, $t1, -0x20 mtc0 $zero, $28 @@ -300,7 +308,7 @@ glabel ipl3_entry // 0xA4000040 sltu $at, $t0, $t1 bnez $at, .LA4000428 addiu $t0, $t0, 0x20 - cn_li $t0, EXCEPTION_TLB_MISS + cn_li $t0, UT_VEC addiu $t1, $t0, 0x2000 addiu $t1, $t1, -0x10 .LA4000448: @@ -310,7 +318,7 @@ glabel ipl3_entry // 0xA4000040 addiu $t0, $t0, 0x10 .LA4000458: #ifdef VERSION_CN - la $t0, D_CN_0400049C + la $t0, SP_DMEM_CN_UNK0 lui $t1, 0xf ori $t1, $t1, 0xffff and $t0, $t0, $t1 @@ -318,7 +326,7 @@ glabel ipl3_entry // 0xA4000040 lui $t3, 0xfff0 and $t2, $t2, $t3 or $t0, $t0, $t2 - la $t3, D_CN_0400074C + la $t3, SP_DMEM_CN_UNK1 and $t3, $t3, $t1 or $t3, $t3, $t2 lui $t1, 0xa000 @@ -347,15 +355,15 @@ glabel ipl3_entry // 0xA4000040 bnez $t0, .LA40004B8 nop #else - cn_li $t2, SP_DMEM + cn_li $t2, PHYS_TO_K1(SP_DMEM_START) lui $t3, 0xfff0 lui $t1, 0x0010 and $t2, $t2, $t3 - lui $t0, %hi(SP_DMEM_UNK0) + lui $t0, %hi(PHYS_TO_K1(SP_DMEM_UNK0)) addiu $t1, -1 - lui $t3, %hi(SP_DMEM_UNK1) - addiu $t0, %lo(SP_DMEM_UNK0) - addiu $t3, %lo(SP_DMEM_UNK1) + lui $t3, %hi(PHYS_TO_K1(SP_DMEM_UNK1)) + addiu $t0, %lo(PHYS_TO_K1(SP_DMEM_UNK0)) + addiu $t3, %lo(PHYS_TO_K1(SP_DMEM_UNK1)) and $t0, $t0, $t1 and $t3, $t3, $t1 lui $t1, 0xa000 @@ -369,31 +377,31 @@ glabel ipl3_entry // 0xA4000040 addiu $t1, $t1, 4 bnez $at, .LA4000498 sw $t5, -4($t1) - cn_li $t4, EXCEPTION_TLB_MISS + cn_li $t4, UT_VEC jr $t4 nop - lui $t3, %hi(D_B0000008) - lw $t1, %lo(D_B0000008)($t3) + lui $t3, %hi(PHYS_TO_CART(CART_ENTRYPOINT)) + lw $t1, %lo(PHYS_TO_CART(CART_ENTRYPOINT))($t3) lui $t2, (0x1FFFFFFF >> 16) ori $t2, (0x1FFFFFFF & 0xFFFF) - lui $at, %hi(PI_DRAM_ADDR_REG) + lui $at, %hi(PHYS_TO_K1(PI_DRAM_ADDR_REG)) and $t1, $t1, $t2 - sw $t1, %lo(PI_DRAM_ADDR_REG)($at) - lui $t0, %hi(PI_STATUS_REG) + sw $t1, %lo(PHYS_TO_K1(PI_DRAM_ADDR_REG))($at) + lui $t0, %hi(PHYS_TO_K1(PI_STATUS_REG)) .LA40004D0: - lw $t0, %lo(PI_STATUS_REG)($t0) - andi $t0, $t0, 2 + lw $t0, %lo(PHYS_TO_K1(PI_STATUS_REG))($t0) + andi $t0, $t0, PI_STATUS_IO_BUSY bnezl $t0, .LA40004D0 - lui $t0, %hi(PI_STATUS_REG) + lui $t0, %hi(PHYS_TO_K1(PI_STATUS_REG)) #endif - li $t0, 0x1000 + li $t0, INITIAL_DMA_ROMPOS add $t0, $t0, $t3 and $t0, $t0, $t2 - lui $at, %hi(PI_CART_ADDR_REG) - sw $t0, %lo(PI_CART_ADDR_REG)($at) - cn_li $t2, 0x000FFFFF - lui $at, %hi(PI_WR_LEN_REG) - sw $t2, %lo(PI_WR_LEN_REG)($at) + lui $at, %hi(PHYS_TO_K1(PI_CART_ADDR_REG)) + sw $t0, %lo(PHYS_TO_K1(PI_CART_ADDR_REG))($at) + cn_li $t2, INITIAL_DMA_LEN + lui $at, %hi(PHYS_TO_K1(PI_WR_LEN_REG)) + sw $t2, %lo(PHYS_TO_K1(PI_WR_LEN_REG))($at) .LA4000514: nop @@ -424,8 +432,8 @@ glabel ipl3_entry // 0xA4000040 nop nop nop - lui $t3, %hi(PI_STATUS_REG) - lw $t3, %lo(PI_STATUS_REG)($t3) + lui $t3, %hi(PHYS_TO_K1(PI_STATUS_REG)) + lw $t3, %lo(PHYS_TO_K1(PI_STATUS_REG))($t3) andi $t3, $t3, 0x1 bnez $t3, .LA4000514 nop @@ -496,39 +504,39 @@ glabel ipl3_entry // 0xA4000040 nop #endif #ifdef VERSION_CN - lui $t1, %hi(SP_PC) - lw $t1, %lo(SP_PC)($t1) + lui $t1, %hi(PHYS_TO_K1(SP_PC_REG)) + lw $t1, %lo(PHYS_TO_K1(SP_PC_REG))($t1) beqz $t1, .LA4000698 nop addiu $t2, $zero, 0x41 - lui $at, %hi(SP_STATUS_REG) - sw $t2, %lo(SP_STATUS_REG)($at) - lui $at, %hi(SP_PC) - sw $zero, %lo(SP_PC)($at) + lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) + sw $t2, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) + lui $at, %hi(PHYS_TO_K1(SP_PC_REG)) + sw $zero, %lo(PHYS_TO_K1(SP_PC_REG))($at) .LA4000698: li $t3, 0x00AAAAAE - lui $at, %hi(SP_STATUS_REG) - sw $t3, %lo(SP_STATUS_REG)($at) + lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) + sw $t3, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) li $t0, 1365 - lui $at, %hi(MI_INTR_MASK_REG) - sw $t0, %lo(MI_INTR_MASK_REG)($at) - lui $at, %hi(SI_STATUS_REG) - sw $zero, %lo(SI_STATUS_REG)($at) - lui $at, %hi(AI_STATUS_REG) - sw $zero, %lo(AI_STATUS_REG)($at) + lui $at, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) + sw $t0, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($at) + lui $at, %hi(PHYS_TO_K1(SI_STATUS_REG)) + sw $zero, %lo(PHYS_TO_K1(SI_STATUS_REG))($at) + lui $at, %hi(PHYS_TO_K1(AI_STATUS_REG)) + sw $zero, %lo(PHYS_TO_K1(AI_STATUS_REG))($at) li $t1, 2048 - lui $at, %hi(MI_MODE_REG) - sw $t1, %lo(MI_MODE_REG)($at) + lui $at, %hi(PHYS_TO_K1(MI_MODE_REG)) + sw $t1, %lo(PHYS_TO_K1(MI_MODE_REG))($at) li $t1, 2 - lui $at, %hi(PI_STATUS_REG) - sw $t1, %lo(PI_STATUS_REG)($at) + lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) + sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) lui $t0, (0xA0000300 >> 16) ori $t0, (0xA0000300 & 0xFFFF) sw $s4, ($t0) sw $s3, 4($t0) #else - lui $t3, %hi(D_B0000008) - lw $a0, %lo(D_B0000008)($t3) + lui $t3, %hi(PHYS_TO_CART(CART_ENTRYPOINT)) + lw $a0, %lo(PHYS_TO_CART(CART_ENTRYPOINT))($t3) move $a1, $s6 lui $at, (0x5D588B65 >> 16) ori $at, (0x5D588B65 & 0xFFFF) @@ -582,11 +590,11 @@ glabel ipl3_entry // 0xA4000040 xor $a3, $t6, $t3 xor $t8, $s0, $a2 xor $s0, $t8, $t4 - lui $t3, %hi(D_B0000010) - lw $t0, %lo(D_B0000010)($t3) + lui $t3, %hi(PHYS_TO_CART(CART_CHECKSUM0)) + lw $t0, %lo(PHYS_TO_CART(CART_CHECKSUM0))($t3) bne $a3, $t0, halt - nop - lw $t0, %lo(D_B0000014)($t3) + nop + lw $t0, %lo(PHYS_TO_CART(CART_CHECKSUM1))($t3) bne $s0, $t0, halt nop bal func_A4000690 @@ -597,36 +605,36 @@ halt: nop func_A4000690: - lui $t1, %hi(SP_PC) - lw $t1, %lo(SP_PC)($t1) + lui $t1, %hi(PHYS_TO_K1(SP_PC_REG)) + lw $t1, %lo(PHYS_TO_K1(SP_PC_REG))($t1) lw $s0, 0x14($sp) lw $ra, 0x1c($sp) beqz $t1, .LA40006BC addiu $sp, $sp, 0x20 li $t2, 65 - lui $at, %hi(SP_STATUS_REG) - sw $t2, %lo(SP_STATUS_REG)($at) - lui $at, %hi(SP_PC) - sw $zero, %lo(SP_PC)($at) + lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) + sw $t2, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) + lui $at, %hi(PHYS_TO_K1(SP_PC_REG)) + sw $zero, %lo(PHYS_TO_K1(SP_PC_REG))($at) .LA40006BC: li $t3, 0x00AAAAAE - lui $at, %hi(SP_STATUS_REG) - sw $t3, %lo(SP_STATUS_REG)($at) - lui $at, %hi(MI_INTR_MASK_REG) + lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) + sw $t3, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) + lui $at, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) li $t0, 1365 - sw $t0, %lo(MI_INTR_MASK_REG)($at) - lui $at, %hi(SI_STATUS_REG) - sw $zero, %lo(SI_STATUS_REG)($at) - lui $at, %hi(AI_STATUS_REG) - sw $zero, %lo(AI_STATUS_REG)($at) - lui $at, %hi(MI_MODE_REG) + sw $t0, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($at) + lui $at, %hi(PHYS_TO_K1(SI_STATUS_REG)) + sw $zero, %lo(PHYS_TO_K1(SI_STATUS_REG))($at) + lui $at, %hi(PHYS_TO_K1(AI_STATUS_REG)) + sw $zero, %lo(PHYS_TO_K1(AI_STATUS_REG))($at) + lui $at, %hi(PHYS_TO_K1(MI_BASE_REG)) li $t1, 2048 - sw $t1, %lo(MI_MODE_REG)($at) + sw $t1, %lo(PHYS_TO_K1(MI_BASE_REG))($at) li $t1, 2 - lui $at, %hi(PI_STATUS_REG) + lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) lui $t0, (0xA0000300 >> 16) ori $t0, (0xA0000300 & 0xFFFF) - sw $t1, %lo(PI_STATUS_REG)($at) + sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) sw $s7, 0x14($t0) #endif sw $s5, 0xc($t0) @@ -647,7 +655,7 @@ func_A4000690: cn_li $t1, 0xb0000000 .LA4000730: sw $t1, 0x8($t0) - cn_li $t0, SP_DMEM + cn_li $t0, PHYS_TO_K1(SP_DMEM_START) addi $t1, $t0, 0x1000 #ifdef VERSION_CN .LA4000710: @@ -661,7 +669,7 @@ func_A4000690: bne $t0, $t1, .LA4000740 sw $zero, -4($t0) #endif - cn_li $t0, SP_IMEM + cn_li $t0, PHYS_TO_K1(SP_IMEM_START) addi $t1, $t0, 0x1000 #ifdef VERSION_CN .LA400072C: @@ -675,8 +683,8 @@ func_A4000690: bne $t0, $t1, .LA4000758 sw $zero, -4($t0) #endif - lui $t3, %hi(D_B0000008) - lw $t1, %lo(D_B0000008)($t3) + lui $t3, %hi(PHYS_TO_CART(CART_ENTRYPOINT)) + lw $t1, %lo(PHYS_TO_CART(CART_ENTRYPOINT))($t3) jr $t1 nop nop @@ -1074,8 +1082,8 @@ func_A4000A40: bne $a1, $k1, .LA4000AC0 sw $t7, ($s5) #endif - lui $k0, %hi(MI_MODE_REG) - sw $zero, %lo(MI_MODE_REG)($k0) + lui $k0, %hi(PHYS_TO_K1(MI_BASE_REG)) + sw $zero, %lo(PHYS_TO_K1(MI_BASE_REG))($k0) .LA4000AC0: lw $ra, 0x1c($sp) #ifdef VERSION_CN @@ -1094,14 +1102,14 @@ func_A4000AD0: move $fp, $zero #endif li $k0, 0x2000 - lui $k1, %hi(MI_MODE_REG) - sw $k0, %lo(MI_MODE_REG)($k1) + lui $k1, %hi(PHYS_TO_K1(MI_BASE_REG)) + sw $k0, %lo(PHYS_TO_K1(MI_BASE_REG))($k1) #ifndef VERSION_CN move $fp, $zero #endif lw $fp, ($s5) li $k0, 0x1000 - sw $k0, %lo(MI_MODE_REG)($k1) + sw $k0, %lo(PHYS_TO_K1(MI_BASE_REG))($k1) #ifdef VERSION_CN move $k0, $zero #endif @@ -1144,3 +1152,5 @@ func_A4000AD0: nop nop #endif + +.end ipl3_entry diff --git a/asm/entry.s b/asm/entry.s index e0f53fea..80c593f1 100644 --- a/asm/entry.s +++ b/asm/entry.s @@ -4,45 +4,50 @@ #include "macros.inc" - .section .text, "ax" glabel entry_point -.if VERSION_CN == 1 +#ifdef VERSION_CN + // Get main segment bss address and size lui $t0, %lo(_mainSegmentNoloadStartHi) ori $t0, %lo(_mainSegmentNoloadStartLo) lui $t1, %lo(_mainSegmentNoloadSizeHi) ori $t1, %lo(_mainSegmentNoloadSizeLo) -.L80249010: - sw $zero, ($t0) - sw $zero, 4($t0) - addi $t0, $t0, 8 - addi $t1, $t1, -8 - bnez $t1, .L80249010 - nop +.clear_bytes: + // Clear bss section until they are zeroed out + sw $zero, ($t0) // Clear 4 bytes + sw $zero, 4($t0) // Clear the next 4 bytes + addi $t0, $t0, 8 // Increment the address of bytes to clear + addi $t1, $t1, -8 // Subtract 8 bytes from the amount remaining + bnez $t1, .clear_bytes // Continue clearing until clear_bytes is 0 + nop + // Get init function and idle thread stack lui $sp, %lo(gIdleThreadStackHi) ori $sp, %lo(gIdleThreadStackLo) lui $t2, %lo(main_funcHi) ori $t2, %lo(main_funcLo) - jr $t2 - nop -.else - lui $t0, %hi(_mainSegmentNoloadStart) // $t0, 0x8034 - lui $t1, %lo(_mainSegmentNoloadSizeHi) // lui $t1, 2 - addiu $t0, %lo(_mainSegmentNoloadStart) // addiu $t0, $t0, -0x6df0 - ori $t1, %lo(_mainSegmentNoloadSizeLo) // ori $t1, $t1, 0xcee0 -.L80246010: - addi $t1, $t1, -8 - sw $zero, ($t0) - sw $zero, 4($t0) - bnez $t1, .L80246010 - addi $t0, $t0, 8 - lui $t2, %hi(main_func) // $t2, 0x8024 - lui $sp, %hi(gIdleThreadStack) // $sp, 0x8020 - addiu $t2, %lo(main_func) // addiu $t2, $t2, 0x6dc4 - jr $t2 - addiu $sp, %lo(gIdleThreadStack) // addiu $sp, $sp, 0xa00 -.endif + jr $t2 // Jump to the init function + nop +#else + // Get main segment bss address and size + lui $t0, %hi(_mainSegmentNoloadStart) + lui $t1, %lo(_mainSegmentNoloadSizeHi) + addiu $t0, %lo(_mainSegmentNoloadStart) + ori $t1, %lo(_mainSegmentNoloadSizeLo) +.clear_bytes: + // Clear bss section until they are zeroed out + addi $t1, $t1, -8 // Subtract 8 bytes from the amount remaining + sw $zero, ($t0) // Clear 4 bytes + sw $zero, 4($t0) // Clear the next 4 bytes + bnez $t1, .clear_bytes // Continue clearing until clear_bytes is 0 + addi $t0, $t0, 8 // Increment the address of bytes to clear + // Get init function and idle thread stack + lui $t2, %hi(main_func) + lui $sp, %hi(gIdleThreadStack) + addiu $t2, %lo(main_func) + jr $t2 // Jump to the init function + addiu $sp, %lo(gIdleThreadStack) +#endif nop nop nop diff --git a/asm/rom_header.s b/asm/rom_header.s index 0f6cd83c..82dd3b3b 100644 --- a/asm/rom_header.s +++ b/asm/rom_header.s @@ -8,15 +8,9 @@ .word entry_point /* Entrypoint */ /* Revision */ -#ifdef VERSION_SH - .word 0x00001448 -#elif defined(VERSION_CN) - .word 0x0000144C -#elif defined(VERSION_EU) - .word 0x00001446 -#else /* NTSC-U and NTSC-J 1.0 */ - .word 0x00001444 -#endif +.half 0x0000 +.byte 20 /* Major version 2.0 */ +.ascii LIBULTRA_STR_VER /* Minor Version */ #ifdef VERSION_CN .fill 0x30 diff --git a/include/PR/bcp.h b/include/PR/bcp.h new file mode 100644 index 00000000..c7bc72af --- /dev/null +++ b/include/PR/bcp.h @@ -0,0 +1,97 @@ +#ifndef _BCP_H_ +#define _BCP_H_ + +#ifdef BBPLAYER +#include "rcp.h" + +/** + * MIPS Interface (MI) Additional Registers + */ + +//! MI_SK_EXCEPTION_REG ? +#define MI_14_REG (MI_BASE_REG + 0x14) + +//! MI_SK_WATCHDOG_TIMER ? +#define MI_18_REG (MI_BASE_REG + 0x18) + +//! ? +#define MI_30_REG (MI_BASE_REG + 0x30) + +//! MI_HW_INTR_REG ? +#define MI_38_REG (MI_BASE_REG + 0x38) + +//! MI_HW_INTR_MASK_REG ? +#define MI_3C_REG (MI_BASE_REG + 0x3C) + +/** + * Peripheral Interface (PI) Additional Registers + */ + +//! PI_ATB_UPPER_REG ? +#define PI_40_REG (PI_BASE_REG + 0x40) + +//! ? +#define PI_44_REG (PI_BASE_REG + 0x44) + +//! PI_CARD_CNT_REG ? +#define PI_48_REG (PI_BASE_REG + 0x48) + +//! ? +#define PI_4C_REG (PI_BASE_REG + 0x4C) + +//! PI_AES_CNT_REG ? +#define PI_50_REG (PI_BASE_REG + 0x50) + +//! PI_ALLOWED_IO_REG ? +#define PI_54_REG (PI_BASE_REG + 0x54) + +//! PI_EX_RD_LEN_REG ? +#define PI_58_REG (PI_BASE_REG + 0x58) + +//! PI_EX_WR_LEN_REG ? +#define PI_5C_REG (PI_BASE_REG + 0x5C) + +//! PI_MISC_REG ? +#define PI_60_REG (PI_BASE_REG + 0x60) + +//! ? +#define PI_64_REG (PI_BASE_REG + 0x64) + +//! PI_CARD_BLK_OFFSET_REG ? +#define PI_70_REG (PI_BASE_REG + 0x70) + +//! PI_EX_DMA_BUF ? +#define PI_10000_REG(i) (PI_BASE_REG + 0x10000 + (i)) + +//! PI_ATB_LOWER_REG ? +#define PI_10500_REG(i) (PI_BASE_REG + 0x10500 + (i) * 4) + +/** + * Serial Interface (SI) Additional Registers + */ + +//! ? +#define SI_0C_REG (SI_BASE_REG + 0x0C) + +//! ? +#define SI_1C_REG (SI_BASE_REG + 0x1C) + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +extern u8 *__osBbEepromAddress; +extern u32 __osBbEepromSize; +extern u32 __osBbFlashAddress; +extern u32 __osBbFlashSize; +extern u32 __osBbSramAddress; +extern u32 __osBbSramSize; +extern u32 *__osBbPakAddress[]; +extern u32 __osBbPakSize; +extern u32 __osBbIsBb; +extern u32 __osBbHackFlags; + +void skKeepAlive(void); + +#endif + +#endif +#endif diff --git a/include/PR/gu.h b/include/PR/gu.h index 6527777d..7fc4b07c 100644 --- a/include/PR/gu.h +++ b/include/PR/gu.h @@ -1,29 +1,99 @@ -#ifndef _ULTRA64_GU_H_ -#define _ULTRA64_GU_H_ +#ifndef _GU_H_ +#define _GU_H_ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/************************************************************************** + * + * $Revision: 1.48 $ + * $Date: 1999/07/13 08:00:20 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/gu.h,v $ + * + **************************************************************************/ #include #include +#include -#define GU_PI 3.1415926 -/* Functions */ +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif -void guPerspectiveF(float mf[4][4], u16 *perspNorm, float fovy, float aspect, - float near, float far, float scale); -void guPerspective(Mtx *m, u16 *perspNorm, float fovy, float aspect, float near, - float far, float scale); -void guOrtho(Mtx *m, float left, float right, float bottom, float top, - float near, float far, float scale); -void guTranslate(Mtx *m, float x, float y, float z); -void guRotate(Mtx *m, float a, float x, float y, float z); -void guScale(Mtx *m, float x, float y, float z); -void guMtxF2L(float mf[4][4], Mtx *m); -void guMtxIdent(Mtx *m); -void guMtxIdentF(float mf[4][4]); -void guMtxL2F(float mf[4][4], Mtx *m); -void guNormalize(float *, float *, float *); +#define M_PI 3.14159265358979323846 + +#define GU_PI 3.1415926 + +#define FTOFIX32(x) (long)((x) * (float)0x00010000) +#ifdef AVOID_UB +#define FIX32TOF(x) ((float)(x) * (1.0f / (float)0x00010000)) +#else +#define FIX32TOF(x) (x / (float)0x00010000) +#endif +#define FTOFRAC8(x) ((int) MIN(((x) * (128.0f)), 127.0f) & 0xff) + +#define FILTER_WRAP 0 +#define FILTER_CLAMP 1 + +/* + * matrix operations: + * + * The 'F' version is floating point, in case the application wants + * to do matrix manipulations and convert to fixed-point at the last + * minute. + */ +extern void guMtxIdent(Mtx *m); +extern void guMtxIdentF(float mf[4][4]); +extern void guOrtho(Mtx *m, float l, float r, float b, float t, + float n, float f, float scale); +extern void guOrthoF(float mf[4][4], float l, float r, float b, float t, + float n, float f, float scale); +extern void guPerspective(Mtx *m, u16 *perspNorm, float fovy, + float aspect, float near, float far, float scale); +extern void guPerspectiveF(float mf[4][4], u16 *perspNorm, float fovy, + float aspect, float near, float far, float scale); +extern void guRotate(Mtx *m, float a, float x, float y, float z); +extern void guRotateF(float mf[4][4], float a, float x, float y, float z); +extern void guScale(Mtx *m, float x, float y, float z); +extern void guScaleF(float mf[4][4], float x, float y, float z); +extern void guTranslate(Mtx *m, float x, float y, float z); +extern void guTranslateF(float mf[4][4], float x, float y, float z); +extern void guMtxF2L(float mf[4][4], Mtx *m); +extern void guMtxL2F(float mf[4][4], Mtx *m); + +/* vector utility: */ +extern void guNormalize(float *x, float *y, float *z); /* Used only in Fast3DEX2 */ -void guLookAtReflect (Mtx *m, LookAt *l, float xEye, float yEye, float zEye, - float xAt, float yAt, float zAt, - float xUp, float yUp, float zUp); -#endif +extern void guLookAtReflect(Mtx *m, LookAt *l, + float xEye, float yEye, float zEye, + float xAt, float yAt, float zAt, + float xUp, float yUp, float zUp); +extern void guLookAtReflectF(float mf[4][4], LookAt *l, + float xEye, float yEye, float zEye, + float xAt, float yAt, float zAt, + float xUp, float yUp, float zUp); + +/* + * Math functions + */ +extern float sinf(float); +extern double sin(double); +extern float cosf(float); +extern double cos(double); + +extern float sqrtf(float); + +#endif /* !_GU_H_ */ diff --git a/include/PR/ique.h b/include/PR/ique.h deleted file mode 100644 index b6a3ef6e..00000000 --- a/include/PR/ique.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef IQUE_H -#define IQUE_H - -#include "rcp.h" - -#define MI_SK_EXCEPTION_REG (MI_BASE_REG+0x14) -#define MI_SK_WATCHDOG_TIMER (MI_BASE_REG+0x18) - -// Hardware interrupts -// 0x40 = NAND DMA, 0x80 = MD, 0x100 = RDB, 0x200 = AES, -// 0x400 = PI_ERR, 0x800 = USB0, 0x1000 = USB1, 0x2000 = NAND -#define MI_HW_INTR_REG (MI_BASE_REG+0x38) -#define MI_HW_INTR_MASK_REG (MI_BASE_REG+0x3C) - -#define PI_CARD_ADDR_REG (PI_BASE_REG+0x48) -#define PI_EX_RD_LEN_REG (PI_BASE_REG+0x58) -#define PI_EX_WR_LEN_REG (PI_BASE_REG+0x5C) -#define PI_MISC_REG (PI_BASE_REG+0x60) - -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) - -extern u8 *__osBbEepromAddress; -extern u32 __osBbEepromSize; -extern u32 __osBbFlashAddress; -extern u32 __osBbFlashSize; -extern u32 __osBbSramAddress; -extern u32 __osBbSramSize; -extern u32 *__osBbPakAddress[]; -extern u32 __osBbPakSize; -extern u32 __osBbIsBb; -extern u32 __osBbHackFlags; - -void skKeepAlive(void); - -#endif - -#endif diff --git a/include/PR/libaudio.h b/include/PR/libaudio.h index 0a8797d7..a7c6c56e 100644 --- a/include/PR/libaudio.h +++ b/include/PR/libaudio.h @@ -1,7 +1,195 @@ -#ifndef _ULTRA64_LIBAUDIO_H_ -#define _ULTRA64_LIBAUDIO_H_ +/*==================================================================== + * libaudio.h + * + * Copyright 1993, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ -#include "abi.h" +/************************************************************************** + * + * $Revision: 1.173 $ + * $Date: 1997/12/01 12:42:21 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/libaudio.h,v $ + * + **************************************************************************/ + +#ifndef __LIB_AUDIO__ +#define __LIB_AUDIO__ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include +#include + +/*********************************************************************** + * misc defines + ***********************************************************************/ + +typedef s32 ALMicroTime; +typedef u8 ALPan; + +/*********************************************************************** + * Error handling + ***********************************************************************/ + +#ifdef _DEBUG +#define ALFailIf(condition, error) \ + if (condition) { \ + __osError(error, 0); \ + return; } + +#else +#define ALFailIf(condition, error) \ + if (condition) { \ + return; } +#endif + +#ifdef _DEBUG +#define ALFlagFailIf(condition, flag, error) \ + if (condition) { \ + if(flag) __osError(error, 0); \ + return; } + +#else +#define ALFlagFailIf(condition, flag, error) \ + if (condition) { \ + return; } +#endif + +/*********************************************************************** + * Macros + ***********************************************************************/ + +#define ALBnkfPatch(src, base, type) (type)((uintptr_t) src + (uintptr_t) base) + +/*********************************************************************** + * data structures for sound banks + ***********************************************************************/ + +#define AL_BANK_VERSION 0x4231 /* 'B1' */ + +/* Possible wavetable types */ +enum {AL_ADPCM_WAVE = 0, + AL_RAW16_WAVE}; + +typedef struct { + s32 order; + s32 npredictors; + s16 book[1]; /* Actually variable size. Must be 8-byte aligned */ +} ALADPCMBook; + +typedef struct { + u32 start; + u32 end; + u32 count; + ADPCM_STATE state; +} ALADPCMloop; + +typedef struct { + u32 start; + u32 end; + u32 count; +} ALRawLoop; + +typedef struct { + ALMicroTime attackTime; + ALMicroTime decayTime; + ALMicroTime releaseTime; + u8 attackVolume; + u8 decayVolume; +} ALEnvelope; + +typedef struct { + u8 velocityMin; + u8 velocityMax; + u8 keyMin; + u8 keyMax; + u8 keyBase; + s8 detune; +} ALKeyMap; + +typedef struct { + ALADPCMloop *loop; + ALADPCMBook *book; +} ALADPCMWaveInfo; + +typedef struct { + ALRawLoop *loop; +} ALRAWWaveInfo; + +typedef struct ALWaveTable_s { + u8 *base; /* ptr to start of wave data */ + s32 len; /* length of data in bytes */ + u8 type; /* compression type */ + u8 flags; /* offset/address flags */ + union { + ALADPCMWaveInfo adpcmWave; + ALRAWWaveInfo rawWave; + } waveInfo; +} ALWaveTable; + +typedef struct ALSound_s { + ALEnvelope *envelope; + ALKeyMap *keyMap; + ALWaveTable *wavetable; /* offset to wavetable struct */ + ALPan samplePan; + u8 sampleVolume; + u8 flags; +} ALSound; + +typedef struct { + u8 volume; /* overall volume for this instrument */ + ALPan pan; /* 0 = hard left, 127 = hard right */ + u8 priority; /* voice priority for this instrument */ + u8 flags; + u8 tremType; /* the type of tremelo osc. to use */ + u8 tremRate; /* the rate of the tremelo osc. */ + u8 tremDepth; /* the depth of the tremelo osc */ + u8 tremDelay; /* the delay for the tremelo osc */ + u8 vibType; /* the type of tremelo osc. to use */ + u8 vibRate; /* the rate of the tremelo osc. */ + u8 vibDepth; /* the depth of the tremelo osc */ + u8 vibDelay; /* the delay for the tremelo osc */ + s16 bendRange; /* pitch bend range in cents */ + s16 soundCount; /* number of sounds in this array */ + ALSound *soundArray[1]; +} ALInstrument; + +typedef struct ALBank_s { + s16 instCount; /* number of programs in this bank */ + u8 flags; + u8 pad; + s32 sampleRate; /* e.g. 44100, 22050, etc... */ + ALInstrument *percussion; /* default percussion for GM */ + ALInstrument *instArray[1]; /* ARRAY of instruments */ +} ALBank; + +typedef struct { /* Note: sizeof won't be correct */ + s16 revision; /* format revision of this file */ + s16 bankCount; /* number of banks */ + ALBank *bankArray[1]; /* ARRAY of bank offsets */ +} ALBankFile; + +void alBnkfNew(ALBankFile *f, u8 *table); + +/*********************************************************************** + * Sequence Files + ***********************************************************************/ typedef struct { @@ -48,4 +236,8 @@ typedef struct void alSeqFileNew(ALSeqFile *f, u8 *base); +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + #endif diff --git a/include/PR/libultra.h b/include/PR/libultra.h deleted file mode 100644 index f0dab415..00000000 --- a/include/PR/libultra.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _LIBULTRA_H -#define _LIBULTRA_H - -#define TV_TYPE_NTSC 1 -#define TV_TYPE_PAL 0 -#define TV_TYPE_MPAL 2 - -#define RESET_TYPE_COLD_RESET 0 -#define RESET_TYPE_NMI 1 -#define RESET_TYPE_BOOT_DISK 2 - -extern u32 osTvType; -extern u32 osRomBase; -extern u32 osResetType; -extern u32 osMemSize; -extern u8 osAppNmiBuffer[64]; - -#endif /* _LIBULTRA_H */ diff --git a/include/PR/os.h b/include/PR/os.h index d10160cb..86e6ae93 100644 --- a/include/PR/os.h +++ b/include/PR/os.h @@ -1,4 +1,5 @@ + /*==================================================================== * os.h * @@ -19,58 +20,42 @@ * Copyright Laws of the United States. *====================================================================*/ -/************************************************************************** - * - * $Revision: 1.149 $ - * $Date: 1997/12/15 04:30:52 $ - * $Source: /disk6/Master/cvsmdev2/PR/include/os.h,v $ - * - **************************************************************************/ - +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os.h,v $ + $Revision: 1.168 $ + $Date: 2000/06/15 06:24:52 $ + *---------------------------------------------------------------------*/ #ifndef _OS_H_ -#define _OS_H_ +#define _OS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef _LANGUAGE_C_PLUS_PLUS extern "C" { #endif #include -#include "PR/os_message.h" - -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) - -/************************************************************************** - * - * Type definitions - * - */ - -/* - * Structure for device manager block - */ -typedef struct { - s32 active; /* Status flag */ - OSThread *thread; /* Calling thread */ - OSMesgQueue *cmdQueue; /* Command queue */ - OSMesgQueue *evtQueue; /* Event queue */ - OSMesgQueue *acsQueue; /* Access queue */ - /* Raw DMA routine */ - s32 (*dma)(s32, u32, void *, u32); - s32 (*edma)(OSPiHandle *, s32, u32, void *, u32); -} OSDevMgr; - -/* - * Structure for Profiler - */ -typedef struct { - u16 *histo_base; /* histogram base */ - u32 histo_size; /* histogram size */ - u32 *text_start; /* start of text segment */ - u32 *text_end; /* end of text segment */ -} OSProf; - -#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ /************************************************************************** * @@ -78,178 +63,18 @@ typedef struct { * */ -/* Thread states */ - -#define OS_STATE_STOPPED 1 -#define OS_STATE_RUNNABLE 2 -#define OS_STATE_RUNNING 4 -#define OS_STATE_WAITING 8 - -/* Flags for debugging purpose */ - -#define OS_FLAG_CPU_BREAK 1 /* Break exception has occurred */ -#define OS_FLAG_FAULT 2 /* CPU fault has occurred */ - -/* Interrupt masks */ - -#define OS_IM_NONE 0x00000001 -#define OS_IM_SW1 0x00000501 -#define OS_IM_SW2 0x00000601 -#define OS_IM_CART 0x00000c01 -#define OS_IM_PRENMI 0x00001401 -#define OS_IM_RDBWRITE 0x00002401 -#define OS_IM_RDBREAD 0x00004401 -#define OS_IM_COUNTER 0x00008401 -#define OS_IM_CPU 0x0000ff01 -#define OS_IM_SP 0x00010401 -#define OS_IM_SI 0x00020401 -#define OS_IM_AI 0x00040401 -#define OS_IM_VI 0x00080401 -#define OS_IM_PI 0x00100401 -#define OS_IM_DP 0x00200401 -#define OS_IM_ALL 0x003fff01 -#define RCP_IMASK 0x003f0000 -#define RCP_IMASKSHIFT 16 - -/* Recommended thread priorities for the system threads */ - -#define OS_PRIORITY_MAX 255 -#define OS_PRIORITY_VIMGR 254 -#define OS_PRIORITY_RMON 250 -#define OS_PRIORITY_RMONSPIN 200 -#define OS_PRIORITY_PIMGR 150 -#define OS_PRIORITY_SIMGR 140 -#define OS_PRIORITY_APPMAX 127 -#define OS_PRIORITY_IDLE 0 /* Must be 0 */ - -/* Flags to indicate direction of data transfer */ - -#define OS_READ 0 /* device -> RDRAM */ -#define OS_WRITE 1 /* device <- RDRAM */ -#define OS_OTHERS 2 /* for Leo disk only */ - -/* - * I/O message types - */ -#define OS_MESG_TYPE_BASE (10) -#define OS_MESG_TYPE_LOOPBACK (OS_MESG_TYPE_BASE+0) -#define OS_MESG_TYPE_DMAREAD (OS_MESG_TYPE_BASE+1) -#define OS_MESG_TYPE_DMAWRITE (OS_MESG_TYPE_BASE+2) -#define OS_MESG_TYPE_VRETRACE (OS_MESG_TYPE_BASE+3) -#define OS_MESG_TYPE_COUNTER (OS_MESG_TYPE_BASE+4) -#define OS_MESG_TYPE_EDMAREAD (OS_MESG_TYPE_BASE+5) -#define OS_MESG_TYPE_EDMAWRITE (OS_MESG_TYPE_BASE+6) - -/* - * I/O message priority - */ -#define OS_MESG_PRI_NORMAL 0 -#define OS_MESG_PRI_HIGH 1 - -/* - * Page size argument for TLB routines - */ -#define OS_PM_4K 0x0000000 -#define OS_PM_16K 0x0006000 -#define OS_PM_64K 0x001e000 -#define OS_PM_256K 0x007e000 -#define OS_PM_1M 0x01fe000 -#define OS_PM_4M 0x07fe000 -#define OS_PM_16M 0x1ffe000 - /* * Stack size for I/O device managers: PIM (PI Manager), VIM (VI Manager), - * SIM (SI Manager) + * SIM (SI Manager) * */ -#define OS_PIM_STACKSIZE 4096 -#define OS_VIM_STACKSIZE 4096 -#define OS_SIM_STACKSIZE 4096 +#define OS_PIM_STACKSIZE 4096 +#define OS_VIM_STACKSIZE 4096 +#define OS_SIM_STACKSIZE 4096 -#define OS_MIN_STACKSIZE 72 +#define OS_LEO_STACKSIZE 4096 -/* - * Values for osTvType - */ -#define OS_TV_PAL 0 -#define OS_TV_NTSC 1 -#define OS_TV_MPAL 2 - -/* - * Video Interface (VI) mode type - */ -#define OS_VI_NTSC_LPN1 0 /* NTSC */ -#define OS_VI_NTSC_LPF1 1 -#define OS_VI_NTSC_LAN1 2 -#define OS_VI_NTSC_LAF1 3 -#define OS_VI_NTSC_LPN2 4 -#define OS_VI_NTSC_LPF2 5 -#define OS_VI_NTSC_LAN2 6 -#define OS_VI_NTSC_LAF2 7 -#define OS_VI_NTSC_HPN1 8 -#define OS_VI_NTSC_HPF1 9 -#define OS_VI_NTSC_HAN1 10 -#define OS_VI_NTSC_HAF1 11 -#define OS_VI_NTSC_HPN2 12 -#define OS_VI_NTSC_HPF2 13 - -#define OS_VI_PAL_LPN1 14 /* PAL */ -#define OS_VI_PAL_LPF1 15 -#define OS_VI_PAL_LAN1 16 -#define OS_VI_PAL_LAF1 17 -#define OS_VI_PAL_LPN2 18 -#define OS_VI_PAL_LPF2 19 -#define OS_VI_PAL_LAN2 20 -#define OS_VI_PAL_LAF2 21 -#define OS_VI_PAL_HPN1 22 -#define OS_VI_PAL_HPF1 23 -#define OS_VI_PAL_HAN1 24 -#define OS_VI_PAL_HAF1 25 -#define OS_VI_PAL_HPN2 26 -#define OS_VI_PAL_HPF2 27 - -#define OS_VI_MPAL_LPN1 28 /* MPAL - mainly Brazil */ -#define OS_VI_MPAL_LPF1 29 -#define OS_VI_MPAL_LAN1 30 -#define OS_VI_MPAL_LAF1 31 -#define OS_VI_MPAL_LPN2 32 -#define OS_VI_MPAL_LPF2 33 -#define OS_VI_MPAL_LAN2 34 -#define OS_VI_MPAL_LAF2 35 -#define OS_VI_MPAL_HPN1 36 -#define OS_VI_MPAL_HPF1 37 -#define OS_VI_MPAL_HAN1 38 -#define OS_VI_MPAL_HAF1 39 -#define OS_VI_MPAL_HPN2 40 -#define OS_VI_MPAL_HPF2 41 - -/* - * Video Interface (VI) special features - */ -#define OS_VI_GAMMA_ON 0x0001 -#define OS_VI_GAMMA_OFF 0x0002 -#define OS_VI_GAMMA_DITHER_ON 0x0004 -#define OS_VI_GAMMA_DITHER_OFF 0x0008 -#define OS_VI_DIVOT_ON 0x0010 -#define OS_VI_DIVOT_OFF 0x0020 -#define OS_VI_DITHER_FILTER_ON 0x0040 -#define OS_VI_DITHER_FILTER_OFF 0x0080 - -/* - * Video Interface (VI) mode attribute bit - */ -#define OS_VI_BIT_NONINTERLACE 0x0001 /* lo-res */ -#define OS_VI_BIT_INTERLACE 0x0002 /* lo-res */ -#define OS_VI_BIT_NORMALINTERLACE 0x0004 /* hi-res */ -#define OS_VI_BIT_DEFLICKINTERLACE 0x0008 /* hi-res */ -#define OS_VI_BIT_ANTIALIAS 0x0010 -#define OS_VI_BIT_POINTSAMPLE 0x0020 -#define OS_VI_BIT_16PIXEL 0x0040 -#define OS_VI_BIT_32PIXEL 0x0080 -#define OS_VI_BIT_LORES 0x0100 -#define OS_VI_BIT_HIRES 0x0200 -#define OS_VI_BIT_NTSC 0x0400 -#define OS_VI_BIT_PAL 0x0800 +#define OS_MIN_STACKSIZE 72 /* * Leo Disk @@ -257,441 +82,17 @@ typedef struct { /* transfer mode */ -#define LEO_BLOCK_MODE 1 -#define LEO_TRACK_MODE 2 -#define LEO_SECTOR_MODE 3 - -/* - * Controllers number - */ - -#ifndef _HW_VERSION_1 -#define MAXCONTROLLERS 4 -#else -#define MAXCONTROLLERS 6 -#endif - -/* controller errors */ -#define CONT_NO_RESPONSE_ERROR 0x8 -#define CONT_OVERRUN_ERROR 0x4 -#ifdef _HW_VERSION_1 -#define CONT_FRAME_ERROR 0x2 -#define CONT_COLLISION_ERROR 0x1 -#endif - -/* Controller type */ - -#define CONT_ABSOLUTE 0x0001 -#define CONT_RELATIVE 0x0002 -#define CONT_JOYPORT 0x0004 -#define CONT_EEPROM 0x8000 -#define CONT_EEP16K 0x4000 -#define CONT_TYPE_MASK 0x1f07 -#define CONT_TYPE_NORMAL 0x0005 -#define CONT_TYPE_MOUSE 0x0002 - -/* Controller status */ - -#define CONT_CARD_ON 0x01 -#define CONT_CARD_PULL 0x02 -#define CONT_ADDR_CRC_ER 0x04 -#define CONT_EEPROM_BUSY 0x80 - -/* EEPROM TYPE */ - -#define EEPROM_TYPE_4K 0x01 -#define EEPROM_TYPE_16K 0x02 - -/* Buttons */ - -#define CONT_A 0x8000 -#define CONT_B 0x4000 -#define CONT_G 0x2000 -#define CONT_START 0x1000 -#define CONT_UP 0x0800 -#define CONT_DOWN 0x0400 -#define CONT_LEFT 0x0200 -#define CONT_RIGHT 0x0100 -#define CONT_L 0x0020 -#define CONT_R 0x0010 -#define CONT_E 0x0008 -#define CONT_D 0x0004 -#define CONT_C 0x0002 -#define CONT_F 0x0001 - -/* Nintendo's official button names */ - -#define A_BUTTON CONT_A -#define B_BUTTON CONT_B -#define L_TRIG CONT_L -#define R_TRIG CONT_R -#define Z_TRIG CONT_G -#define START_BUTTON CONT_START -#define U_JPAD CONT_UP -#define L_JPAD CONT_LEFT -#define R_JPAD CONT_RIGHT -#define D_JPAD CONT_DOWN -#define U_CBUTTONS CONT_E -#define L_CBUTTONS CONT_C -#define R_CBUTTONS CONT_F -#define D_CBUTTONS CONT_D - -/* definition for EEPROM */ - -#define EEPROM_MAXBLOCKS 64 -#define EEP16K_MAXBLOCKS 256 -#define EEPROM_BLOCK_SIZE 8 - -/* - * PI/EPI - */ -#define PI_DOMAIN1 0 -#define PI_DOMAIN2 1 - -/* - * Profiler constants - */ -#define PROF_MIN_INTERVAL 50 /* microseconds */ +#define LEO_BLOCK_MODE 1 +#define LEO_TRACK_MODE 2 +#define LEO_SECTOR_MODE 3 /* * Boot addresses */ -#define BOOT_ADDRESS_ULTRA 0x80000400 -#define BOOT_ADDRESS_COSIM 0x80002000 -#define BOOT_ADDRESS_EMU 0x20010000 -#define BOOT_ADDRESS_INDY 0x88100000 - -/* - * Size of buffer the retains contents after NMI - */ -#define OS_APP_NMI_BUFSIZE 64 - -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) - -/************************************************************************** - * - * Macro definitions - * - */ - -/* PARTNER-N64 */ -#ifdef PTN64 -#define osReadHost osReadHost_pt -#define osWriteHost osWriteHost_pt -#endif - -/* Get count of valid messages in queue */ -#define MQ_GET_COUNT(mq) ((mq)->validCount) - -/* Figure out if message queue is empty or full */ -#define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq) == 0) -#define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq) >= (mq)->msgCount) - -/* - * CPU counter increments at 3/4 of bus clock rate: - * - * Bus Clock Proc Clock Counter (1/2 Proc Clock) - * --------- ---------- ------------------------ - * 62.5 Mhz 93.75 Mhz 46.875 Mhz - */ -extern u64 osClockRate; - -#define OS_CLOCK_RATE 62500000LL -#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4) -#define OS_NSEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625000LL))/(1000000000LL/15625000LL)) -#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625LL))/(1000000LL/15625LL)) -#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL/15625000LL))/(OS_CPU_COUNTER/15625000LL)) -#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL/15625LL))/(OS_CPU_COUNTER/15625LL)) - -/************************************************************************** - * - * Extern variables - * - */ -extern OSViMode osViModeTable[]; /* Global VI mode table */ - -extern OSViMode osViModeNtscLpn1; /* Individual VI NTSC modes */ -extern OSViMode osViModeNtscLpf1; -extern OSViMode osViModeNtscLan1; -extern OSViMode osViModeNtscLaf1; -extern OSViMode osViModeNtscLpn2; -extern OSViMode osViModeNtscLpf2; -extern OSViMode osViModeNtscLan2; -extern OSViMode osViModeNtscLaf2; -extern OSViMode osViModeNtscHpn1; -extern OSViMode osViModeNtscHpf1; -extern OSViMode osViModeNtscHan1; -extern OSViMode osViModeNtscHaf1; -extern OSViMode osViModeNtscHpn2; -extern OSViMode osViModeNtscHpf2; - -extern OSViMode osViModePalLpn1; /* Individual VI PAL modes */ -extern OSViMode osViModePalLpf1; -extern OSViMode osViModePalLan1; -extern OSViMode osViModePalLaf1; -extern OSViMode osViModePalLpn2; -extern OSViMode osViModePalLpf2; -extern OSViMode osViModePalLan2; -extern OSViMode osViModePalLaf2; -extern OSViMode osViModePalHpn1; -extern OSViMode osViModePalHpf1; -extern OSViMode osViModePalHan1; -extern OSViMode osViModePalHaf1; -extern OSViMode osViModePalHpn2; -extern OSViMode osViModePalHpf2; - -extern OSViMode osViModeMpalLpn1; /* Individual VI MPAL modes */ -extern OSViMode osViModeMpalLpf1; -extern OSViMode osViModeMpalLan1; -extern OSViMode osViModeMpalLaf1; -extern OSViMode osViModeMpalLpn2; -extern OSViMode osViModeMpalLpf2; -extern OSViMode osViModeMpalLan2; -extern OSViMode osViModeMpalLaf2; -extern OSViMode osViModeMpalHpn1; -extern OSViMode osViModeMpalHpf1; -extern OSViMode osViModeMpalHan1; -extern OSViMode osViModeMpalHaf1; -extern OSViMode osViModeMpalHpn2; -extern OSViMode osViModeMpalHpf2; - -extern s32 osRomType; /* Bulk or cartridge ROM. 0=cartridge 1=bulk */ -extern u32 osRomBase; /* Rom base address of the game image */ -extern u32 osTvType; /* 0 = PAL, 1 = NTSC, 2 = MPAL */ -extern u32 osResetType; /* 0 = cold reset, 1 = NMI */ -extern s32 osCicId; -extern s32 osVersion; -extern u32 osMemSize; /* Memory Size */ -extern s32 osAppNMIBuffer[]; - -extern OSIntMask __OSGlobalIntMask; /* global interrupt mask */ -extern OSPiHandle *__osPiTable; /* The head of OSPiHandle link list */ -extern OSPiHandle *__osDiskHandle; /* For exceptasm to get disk info*/ - - - -/************************************************************************** - * - * Function prototypes - * - */ - -/* Thread operations */ - -extern void osCreateThread(OSThread *, OSId, void (*)(void *), - void *, void *, OSPri); -extern void osDestroyThread(OSThread *); -extern void osYieldThread(void); -extern void osStartThread(OSThread *); -extern void osStopThread(OSThread *); -extern OSId osGetThreadId(OSThread *); -extern void osSetThreadPri(OSThread *, OSPri); -extern OSPri osGetThreadPri(OSThread *); - -/* Message operations */ - -extern void osCreateMesgQueue(OSMesgQueue *, OSMesg *, s32); -extern s32 osSendMesg(OSMesgQueue *, OSMesg, s32); -extern s32 osJamMesg(OSMesgQueue *, OSMesg, s32); -extern s32 osRecvMesg(OSMesgQueue *, OSMesg *, s32); - -/* Event operations */ - -extern void osSetEventMesg(OSEvent, OSMesgQueue *, OSMesg); - -/* Interrupt operations */ - -extern OSIntMask osGetIntMask(void); -extern OSIntMask osSetIntMask(OSIntMask); - -/* RDB port operations */ - -extern void osInitRdb(u8 *sendBuf, u32 sendSize); - -/* Cache operations and macros */ - -extern void osInvalDCache(void *, size_t); -extern void osInvalICache(void *, size_t); -extern void osWritebackDCache(void *, size_t); -extern void osWritebackDCacheAll(void); - -#define OS_DCACHE_ROUNDUP_ADDR(x) (void *)(((((u32)(x)+0xf)/0x10)*0x10)) -#define OS_DCACHE_ROUNDUP_SIZE(x) (u32)(((((u32)(x)+0xf)/0x10)*0x10)) - -/* TLB management routines */ - -extern void osMapTLB(s32, OSPageMask, void *, u32, u32, s32); -extern void osMapTLBRdb(void); -extern void osUnmapTLB(s32); -extern void osUnmapTLBAll(void); -extern void osSetTLBASID(s32); - -/* Address translation routines and macros */ - -extern u32 osVirtualToPhysical(void *); -extern void * osPhysicalToVirtual(u32); - -#define OS_K0_TO_PHYSICAL(x) (u32)(((char *)(x)-0x80000000)) -#define OS_K1_TO_PHYSICAL(x) (u32)(((char *)(x)-0xa0000000)) - -#define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000)) -#define OS_PHYSICAL_TO_K1(x) (void *)(((u32)(x)+0xa0000000)) - -/* I/O operations */ - -/* Audio interface (Ai) */ -extern u32 osAiGetStatus(void); -extern u32 osAiGetLength(void); -extern s32 osAiSetFrequency(u32); -extern s32 osAiSetNextBuffer(void *, u32); - -/* Display processor interface (Dp) */ -extern u32 osDpGetStatus(void); -extern void osDpSetStatus(u32); -extern void osDpGetCounters(u32 *); -extern s32 osDpSetNextBuffer(void *, u64); - -/* Peripheral interface (Pi) */ -extern u32 osPiGetStatus(void); -extern s32 osPiGetDeviceType(void); -extern s32 osPiRawWriteIo(u32, u32); -extern s32 osPiRawReadIo(u32, u32 *); -extern s32 osPiRawStartDma(s32, u32, void *, u32); -extern s32 osPiWriteIo(u32, u32); -extern s32 osPiReadIo(u32, u32 *); -extern s32 osPiStartDma(OSIoMesg *, s32, s32, u32, void *, u32, - OSMesgQueue *); -extern void osCreatePiManager(OSPri, OSMesgQueue *, OSMesg *, s32); - -/* Video interface (Vi) */ -extern u32 osViGetStatus(void); -extern u32 osViGetCurrentMode(void); -extern u32 osViGetCurrentLine(void); -extern u32 osViGetCurrentField(void); -extern void *osViGetCurrentFramebuffer(void); -extern void *osViGetNextFramebuffer(void); -extern void osViSetXScale(f32); -extern void osViSetYScale(f32); -extern void osViSetSpecialFeatures(u32); -extern void osViSetMode(OSViMode *); -extern void osViSetEvent(OSMesgQueue *, OSMesg, u32); -extern void osViSwapBuffer(void *); -extern void osViBlack(u8); -extern void osViFade(u8, u16); -extern void osViRepeatLine(u8); -extern void osCreateViManager(OSPri); - -/* Timer interface */ - -extern OSTime osGetTime(void); -extern void osSetTime(OSTime); -extern u32 osSetTimer(OSTimer *, OSTime, OSTime, - OSMesgQueue *, OSMesg); -extern int osStopTimer(OSTimer *); - -/* Controller interface */ - -extern s32 osContInit(OSMesgQueue *, u8 *, OSContStatus *); -extern s32 osContReset(OSMesgQueue *, OSContStatus *); -extern s32 osContStartQuery(OSMesgQueue *); -extern s32 osContStartReadData(OSMesgQueue *); -#ifndef _HW_VERSION_1 -extern s32 osContSetCh(u8); -#endif -extern void osContGetQuery(OSContStatus *); -extern void osContGetReadData(OSContPad *); - -/* file system interface */ - -extern s32 osPfsInitPak(OSMesgQueue *, OSPfs *, int); -extern s32 osPfsRepairId(OSPfs *); -extern s32 osPfsInit(OSMesgQueue *, OSPfs *, int); -extern s32 osPfsReFormat(OSPfs *, OSMesgQueue *, int); -extern s32 osPfsChecker(OSPfs *); -extern s32 osPfsAllocateFile(OSPfs *, u16, u32, u8 *, u8 *, int, s32 *); -extern s32 osPfsFindFile(OSPfs *, u16, u32, u8 *, u8 *, s32 *); -extern s32 osPfsDeleteFile(OSPfs *, u16, u32, u8 *, u8 *); -extern s32 osPfsReadWriteFile(OSPfs *, s32, u8, int, int, u8 *); -extern s32 osPfsFileState(OSPfs *, s32, OSPfsState *); -extern s32 osPfsGetLabel(OSPfs *, u8 *, int *); -extern s32 osPfsSetLabel(OSPfs *, u8 *); -extern s32 osPfsIsPlug(OSMesgQueue *, u8 *); -extern s32 osPfsFreeBlocks(OSPfs *, s32 *); -extern s32 osPfsNumFiles(OSPfs *, s32 *, s32 *); - -/* EEPROM interface */ - -extern s32 osEepromProbe(OSMesgQueue *); -extern s32 osEepromRead(OSMesgQueue *, u8, u8 *); -extern s32 osEepromWrite(OSMesgQueue *, u8, u8 *); -extern s32 osEepromLongRead(OSMesgQueue *, u8, u8 *, int); -extern s32 osEepromLongWrite(OSMesgQueue *, u8, u8 *, int); - -/* MOTOR interface */ - -extern s32 osMotorInit(OSMesgQueue *, OSPfs *, int); -extern s32 osMotorStop(OSPfs *); -extern s32 osMotorStart(OSPfs *); - -#ifdef VERSION_CN -#define MOTOR_START 1 -#define MOTOR_STOP 0 -extern s32 __osMotorAccess(OSPfs *, s32); -#endif - -/* Enhanced PI interface */ - -extern OSPiHandle *osCartRomInit(void); -extern OSPiHandle *osLeoDiskInit(void); -extern OSPiHandle *osDriveRomInit(void); - -extern s32 osEPiDeviceType(OSPiHandle *, OSPiInfo *); -extern s32 osEPiRawWriteIo(OSPiHandle *, u32 , u32); -extern s32 osEPiRawReadIo(OSPiHandle *, u32 , u32 *); -extern s32 osEPiRawStartDma(OSPiHandle *, s32 , u32 , void *, u32 ); -extern s32 osEPiWriteIo(OSPiHandle *, u32 , u32 ); -extern s32 osEPiReadIo(OSPiHandle *, u32 , u32 *); -extern s32 osEPiStartDma(OSPiHandle *, OSIoMesg *, s32); -extern s32 osEPiLinkHandle(OSPiHandle *); - -/* Profiler Interface */ - -extern void osProfileInit(OSProf *, u32 profcnt); -extern void osProfileStart(u32); -extern void osProfileFlush(void); -extern void osProfileStop(void); - -/* Game <> Host data transfer functions */ - -extern s32 osTestHost(void); -extern void osReadHost(void *, u32); -extern void osWriteHost(void *, u32); -extern void osAckRamromRead(void); -extern void osAckRamromWrite(void); - - -/* byte string operations */ - -extern void bcopy(const void *, void *, size_t); -extern int bcmp(const void *, const void *, int); -extern void bzero(void *, size_t); - -/* Miscellaneous operations */ - -extern void osInitialize(void); -extern u32 osGetCount(void); -extern void osExit(void); -extern u32 osGetMemSize(void); - -/* Printf */ - -extern int sprintf(char *s, const char *fmt, ...); -extern void osSyncPrintf(const char *fmt, ...); -extern void osAsyncPrintf(const char *fmt, ...); -extern int osSyncGetChars(char *buf); -extern int osAsyncGetChars(char *buf); - -#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ +#define BOOT_ADDRESS_ULTRA 0x80000400 +#define BOOT_ADDRESS_COSIM 0x80002000 +#define BOOT_ADDRESS_EMU 0x20010000 +#define BOOT_ADDRESS_INDY 0x88100000 #ifdef _LANGUAGE_C_PLUS_PLUS } diff --git a/include/PR/os_cont.h b/include/PR/os_cont.h index 3b51e3ec..e8ca3659 100644 --- a/include/PR/os_cont.h +++ b/include/PR/os_cont.h @@ -93,6 +93,7 @@ typedef struct { /* controller errors */ #define CONT_NO_RESPONSE_ERROR 0x8 #define CONT_OVERRUN_ERROR 0x4 +#define CONT_RANGE_ERROR -1 #ifdef _HW_VERSION_1 #define CONT_FRAME_ERROR 0x2 #define CONT_COLLISION_ERROR 0x1 diff --git a/include/PR/os_convert.h b/include/PR/os_convert.h new file mode 100644 index 00000000..2ae44fc2 --- /dev/null +++ b/include/PR/os_convert.h @@ -0,0 +1,119 @@ + +/*==================================================================== + * os_convert.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_convert.h,v $ + $Revision: 1.2 $ + $Date: 1999/04/21 02:53:11 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_CONVERT_H_ +#define _OS_CONVERT_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Type definitions + * + */ + + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +/************************************************************************** + * + * Global definitions + * + */ + +#define OS_CLOCK_RATE 62500000LL +#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4) + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + +#if LIBULTRA_VERSION > OS_VER_H +#define OS_NSEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625000LL))/(1000000000LL/15625000LL)) +#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625LL))/(1000000LL/15625LL)) +#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL/15625000LL))/(OS_CPU_COUNTER/15625000LL)) +#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL/15625LL))/(OS_CPU_COUNTER/15625LL)) +#else +#define OS_NSEC_TO_CYCLES(n) (((u64)(n)*(osClockRate))/(1000000000LL)) +#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(osClockRate))/(1000000LL)) +#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL))/(osClockRate)) +#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL))/(osClockRate)) +#endif + +/* OS_K?_TO_PHYSICAL macro bug fix for CodeWarrior */ +#ifndef __MWERKS__ +#define OS_K0_TO_PHYSICAL(x) (u32)(((char *)(x)-0x80000000)) +#define OS_K1_TO_PHYSICAL(x) (u32)(((char *)(x)-0xa0000000)) +#else +#define OS_K0_TO_PHYSICAL(x) ((char *)(x)-0x80000000) +#define OS_K1_TO_PHYSICAL(x) ((char *)(x)-0xa0000000) +#endif + +#define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000)) +#define OS_PHYSICAL_TO_K1(x) (void *)(((u32)(x)+0xa0000000)) + + +/************************************************************************** + * + * Extern variables + * + */ + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* Address translation routines and macros */ + +extern uintptr_t osVirtualToPhysical(void *); +extern void * osPhysicalToVirtual(u32); + + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_CONVERT_H_ */ diff --git a/include/PR/os_eeprom.h b/include/PR/os_eeprom.h index b3bca814..21110aca 100644 --- a/include/PR/os_eeprom.h +++ b/include/PR/os_eeprom.h @@ -66,6 +66,10 @@ extern "C" { #define EEP16K_MAXBLOCKS 256 #define EEPROM_BLOCK_SIZE 8 +/* EEPROM SIZE */ + +#define EEPROM_SIZE EEPROM_BLOCK_SIZE * EEPROM_MAXBLOCKS +#define EEP16K_SIZE EEPROM_BLOCK_SIZE * EEP16K_MAXBLOCKS #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) diff --git a/include/PR/os_exception.h b/include/PR/os_exception.h index 245e5e69..925b821f 100644 --- a/include/PR/os_exception.h +++ b/include/PR/os_exception.h @@ -63,6 +63,7 @@ typedef u32 OSHWIntr; /* Interrupt masks */ #define OS_IM_NONE 0x00000001 +#define OS_IM_RCP 0x00000401 #define OS_IM_SW1 0x00000501 #define OS_IM_SW2 0x00000601 #define OS_IM_CART 0x00000c01 diff --git a/include/PR/os_internal.h b/include/PR/os_internal.h index 889048fb..c226809e 100644 --- a/include/PR/os_internal.h +++ b/include/PR/os_internal.h @@ -1,19 +1,41 @@ -#ifndef _ULTRA64_OS_INTERNAL_H_ -#define _ULTRA64_OS_INTERNAL_H_ -#include "PR/os_message.h" +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ -/* Internal functions used by the operating system */ -/* Do not include this header in application code */ +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal.h,v $ + $Revision: 1.20 $ + $Date: 1998/10/09 08:01:09 $ + *---------------------------------------------------------------------*/ -/* Variables */ +#ifndef _OS_INTERNAL_H_ +#define _OS_INTERNAL_H_ -//extern u64 osClockRate; +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif -/* Functions */ +#include -/*u32 __osProbeTLB(void *); -u32 __osDisableInt(void); -void __osRestoreInt(u32);*/ -OSThread *__osGetCurrFaultedThread(void); +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#include "os_internal_reg.h" +#include "os_internal_si.h" +#include "os_internal_vi.h" +#include "os_internal_rsp.h" +#include "os_internal_error.h" +#include "os_internal_debug.h" +#include "os_internal_exception.h" +#endif #endif diff --git a/include/PR/os_internal_debug.h b/include/PR/os_internal_debug.h new file mode 100644 index 00000000..8c5c9ea2 --- /dev/null +++ b/include/PR/os_internal_debug.h @@ -0,0 +1,42 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_debug.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:09 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_DEBUG_H_ +#define _OS_INTERNAL_DEBUG_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Debug port */ +extern int __osAtomicDec(unsigned int *p); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_DEBUG_H */ diff --git a/include/PR/os_internal_error.h b/include/PR/os_internal_error.h new file mode 100644 index 00000000..03f5d40b --- /dev/null +++ b/include/PR/os_internal_error.h @@ -0,0 +1,43 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_error.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:10 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_ERROR_H_ +#define _OS_INTERNAL_ERROR_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Error handling */ + +extern OSThread * __osGetCurrFaultedThread(void); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_ERROR_H */ diff --git a/include/PR/os_internal_exception.h b/include/PR/os_internal_exception.h new file mode 100644 index 00000000..372b13f4 --- /dev/null +++ b/include/PR/os_internal_exception.h @@ -0,0 +1,50 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_exception.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:10 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_EXCEPTION_H_ +#define _OS_INTERNAL_EXCEPTION_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "os.h" + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Routine for HW interrupt "handler" */ +#if LIBULTRA_VERSION >= OS_VER_J +extern void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void), void *stackEnd); +#else +extern void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void)); +#endif + +/* Routine for global interrupt mask */ +extern void __osSetGlobalIntMask(OSHWIntr); +extern void __osResetGlobalIntMask(OSHWIntr); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_EXCEPTION_H */ diff --git a/include/PR/os_internal_reg.h b/include/PR/os_internal_reg.h new file mode 100644 index 00000000..206b721c --- /dev/null +++ b/include/PR/os_internal_reg.h @@ -0,0 +1,57 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_reg.h,v $ + $Revision: 1.2 $ + $Date: 1999/03/10 12:19:14 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_REG_H_ +#define _OS_INTERNAL_REG_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "os.h" + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Routines to get/fetch coprocessor 0 registers */ +extern u32 __osGetCause(void); +extern void __osSetCause(u32); +extern u32 __osGetCompare(void); +extern void __osSetCompare(u32); +extern u32 __osGetConfig(void); +extern void __osSetConfig(u32); +extern void __osSetCount(u32); +extern u32 __osGetSR(void); +extern void __osSetSR(u32); +extern u32 __osDisableInt(void); +extern void __osRestoreInt(u32); +extern u32 __osGetWatchLo(void); +extern void __osSetWatchLo(u32); + +/* Routines to get/set floating-point control and status register */ +extern u32 __osSetFpcCsr(u32); +extern u32 __osGetFpcCsr(void); + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_REG_H */ diff --git a/include/PR/os_internal_rsp.h b/include/PR/os_internal_rsp.h new file mode 100644 index 00000000..f9ea9c7b --- /dev/null +++ b/include/PR/os_internal_rsp.h @@ -0,0 +1,48 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_rsp.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:12 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_RSP_H_ +#define _OS_INTERNAL_RSP_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Signal processor interface (Sp) */ + +extern u32 __osSpGetStatus(void); +extern void __osSpSetStatus(u32); +extern s32 __osSpSetPc(u32); +extern s32 __osSpRawWriteIo(u32, u32); +extern s32 __osSpRawReadIo(u32, u32 *); +extern s32 __osSpRawStartDma(s32, u32, void *, size_t); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_RSP_H */ diff --git a/include/PR/os_internal_si.h b/include/PR/os_internal_si.h new file mode 100644 index 00000000..35f819f7 --- /dev/null +++ b/include/PR/os_internal_si.h @@ -0,0 +1,50 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_si.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:13 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_SI_H_ +#define _OS_INTERNAL_SI_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Serial interface (Si) */ + +extern u32 __osSiGetStatus(void); +extern s32 __osSiRawWriteIo(u32, u32); +extern s32 __osSiRawReadIo(u32, u32 *); +extern s32 __osSiRawStartDma(s32, void *); + +extern void __osSiGetAccess(void); +extern void __osSiRelAccess(void); +extern int __osSiDeviceBusy(void); +extern void __osSiCreateAccessQueue(void); + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_SI_H */ diff --git a/include/PR/os_internal_vi.h b/include/PR/os_internal_vi.h new file mode 100644 index 00000000..d7718083 --- /dev/null +++ b/include/PR/os_internal_vi.h @@ -0,0 +1,96 @@ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_internal_vi.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:13 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_VI_H_ +#define _OS_INTERNAL_VI_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +/************************************************************************** + * + * Global definitions + * + */ + +/* + * Video Interface (VI) states + */ +#define VI_STATE_MODE_UPDATED 0x01 +#define VI_STATE_XSCALE_UPDATED 0x02 +#define VI_STATE_YSCALE_UPDATED 0x04 +#define VI_STATE_CTRL_UPDATED 0x08 // related to control regs changing +#define VI_STATE_BUFFER_UPDATED 0x10 // swap buffer +#define VI_STATE_BLACK 0x20 // probably related to a black screen +#define VI_STATE_REPEATLINE 0x40 // repeat line? +#define VI_STATE_FADE 0x80 // fade + +/* + * Video Interface (VI) masks + */ +#define VI_SCALE_MASK 0xfff //see rcp scale_x/scale_y +#define VI_2_10_FPART_MASK 0x3ff +#define VI_SUBPIXEL_SH 0x10 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* + * Structure for VI context + */ + +typedef struct { + /* 0x0 */ f32 factor; + /* 0x4 */ u16 offset; + /* 0x8 */ u32 scale; +} __OSViScale; + +typedef struct { + /* 0x00 */ u16 state; + /* 0x02 */ u16 retraceCount; + /* 0x04 */ void* framep; + /* 0x08 */ OSViMode *modep; + /* 0x0c */ u32 control; + /* 0x10 */ OSMesgQueue *msgq; + /* 0x14 */ OSMesg *msg; + /* 0x18 */ __OSViScale x; + /* 0x24 */ __OSViScale y; +} __OSViContext; + +/* Video interface (Vi) */ + +extern __OSViContext *__osViGetCurrentContext(void); +extern void __osViSwapContext(void); +extern void __osViInit(void); + +extern __OSViContext *__osViNext; +extern __OSViContext *__osViCurr; + +extern u32 __additional_scanline; + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_VI_H */ diff --git a/include/PR/os_libc.h b/include/PR/os_libc.h index 7dec0e45..5506d669 100644 --- a/include/PR/os_libc.h +++ b/include/PR/os_libc.h @@ -1,18 +1,96 @@ + +/*==================================================================== + * os_libc.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_libc.h,v $ + $Revision: 1.3 $ + $Date: 1999/07/13 01:43:47 $ + *---------------------------------------------------------------------*/ + #ifndef _OS_LIBC_H_ -#define _OS_LIBC_H_ +#define _OS_LIBC_H_ -#include "ultratypes.h" +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif -// Old deprecated functions from strings.h, replaced by memcpy/memset. -extern void bcopy(const void *, void *, size_t); -extern void bzero(void *, size_t); +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Type definitions + * + */ + + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +/************************************************************************** + * + * Global definitions + * + */ + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + + +/************************************************************************** + * + * Extern variables + * + */ + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* byte string operations */ + + +extern void bcopy(const void *, void *, size_t); +extern void bzero(void *, size_t); /* Printf */ -extern int sprintf(char *s, const char *fmt, ...); -extern void osSyncPrintf(const char *fmt, ...); -extern void osAsyncPrintf(const char *fmt, ...); -extern int osSyncGetChars(char *buf); -extern int osAsyncGetChars(char *buf); +extern int sprintf(char *s, const char *fmt, ...); +extern void osSyncPrintf(const char *fmt, ...); + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif #endif /* !_OS_LIBC_H_ */ diff --git a/include/PR/os_misc.h b/include/PR/os_misc.h deleted file mode 100644 index 71e111f1..00000000 --- a/include/PR/os_misc.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ULTRA64_OS_MISC_H_ -#define _ULTRA64_OS_MISC_H_ -#include -/* Miscellaneous OS functions */ - -void osInitialize(void); -u32 osGetCount(void); - -uintptr_t osVirtualToPhysical(void *); - -#endif diff --git a/include/PR/os_motor.h b/include/PR/os_motor.h index eb8c7d6c..9555500f 100644 --- a/include/PR/os_motor.h +++ b/include/PR/os_motor.h @@ -17,7 +17,7 @@ extern "C" { #include #include "os_message.h" #include "os_pfs.h" - +#include "os_version.h" #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) @@ -60,11 +60,17 @@ extern "C" { */ /* Rumble PAK interface */ - extern s32 osMotorInit(OSMesgQueue *, OSPfs *, int); +#define MOTOR_START 1 +#define MOTOR_STOP 0 +extern s32 __osMotorAccess(OSPfs *, s32); +#if LIBULTRA_VERSION >= OS_VER_J && !defined(BBPLAYER) +#define osMotorStart(x) __osMotorAccess((x), MOTOR_START) +#define osMotorStop(x) __osMotorAccess((x), MOTOR_STOP) +#else extern s32 osMotorStop(OSPfs *); extern s32 osMotorStart(OSPfs *); - +#endif #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ diff --git a/include/PR/os_pfs.h b/include/PR/os_pfs.h index 43a39db1..d765e261 100644 --- a/include/PR/os_pfs.h +++ b/include/PR/os_pfs.h @@ -101,6 +101,9 @@ typedef struct { /* File System status */ #define PFS_INITIALIZED 0x1 #define PFS_CORRUPTED 0x2 /* File system was corrupted */ +#define PFS_ID_BROKEN 0x4 +#define PFS_MOTOR_INITIALIZED 0x8 +#define PFS_GBPAK_INITIALIZED 0x10 /* File System error number */ @@ -116,6 +119,26 @@ typedef struct { #define PFS_ERR_ID_FATAL 10 /* dead ram pack */ #define PFS_ERR_DEVICE 11 /* wrong device type*/ +/* Definition for bank */ +#define PFS_ID_BANK_256K 0 +#define PFS_ID_BANK_1M 4 +#define PFS_BANKS_256K 1 + +#define PFS_WRITTEN 2 +#define DEF_DIR_PAGES 2 + +#define PFS_ID_0AREA 1 +#define PFS_ID_1AREA 3 +#define PFS_ID_2AREA 4 +#define PFS_ID_3AREA 6 +#define PFS_LABEL_AREA 7 +#define PFS_ID_PAGE PFS_ONE_PAGE * 0 + +#define PFS_BANK_LAPPED_BY 8 /* => u8 */ +#define PFS_SECTOR_PER_BANK 32 +#define PFS_INODE_DIST_MAP (PFS_BANK_LAPPED_BY * PFS_SECTOR_PER_BANK) +#define PFS_SECTOR_SIZE (PFS_INODE_SIZE_PER_PAGE/PFS_SECTOR_PER_BANK) + #ifdef _LANGUAGE_C_PLUS_PLUS } #endif diff --git a/include/PR/os_pi.h b/include/PR/os_pi.h index 86b961e2..674c18cb 100644 --- a/include/PR/os_pi.h +++ b/include/PR/os_pi.h @@ -1,88 +1,228 @@ -#ifndef _ULTRA64_PI_H_ -#define _ULTRA64_PI_H_ -#include -/* Ultra64 Parallel Interface */ +/*==================================================================== + * os_pi.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ -/* Types */ +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_pi.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:16 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_PI_H_ +#define _OS_PI_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "ultratypes.h" +#include "os_thread.h" +#include "os_message.h" +#include "os_version.h" + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Type definitions + * + */ + +/* + * Structure for Enhanced PI interface + */ + + +/* + * OSTranxInfo is set up for Leo Disk DMA. This info will be maintained + * by exception handler. This is how the PIMGR and the ISR communicate. + */ typedef struct { -#if !defined(VERSION_EU) - u32 errStatus; +#if LIBULTRA_VERSION != OS_VER_F + u32 errStatus; /* error status */ #endif - void *dramAddr; - void *C2Addr; - u32 sectorSize; - u32 C1ErrNum; - u32 C1ErrSector[4]; + void *dramAddr; /* RDRAM buffer address (DMA) */ + void *C2Addr; /* C2 buffer address */ + u32 sectorSize; /* size of transfering sector */ + u32 C1ErrNum; /* total # of C1 errors */ + u32 C1ErrSector[4]; /* error sectors */ } __OSBlockInfo; typedef struct { - u32 cmdType; // 0 - u16 transferMode; // 4 - u16 blockNum; // 6 - s32 sectorNum; // 8 - uintptr_t devAddr; // c -#if defined(VERSION_EU) - u32 errStatus; //error status added moved to blockinfo + u32 cmdType; /* for disk only */ + u16 transferMode; /* Block, Track, or sector? */ + u16 blockNum; /* which block is transfering */ + s32 sectorNum; /* which sector is transfering */ + uintptr_t devAddr; /* Device buffer address */ +#if LIBULTRA_VERSION == OS_VER_F + u32 errStatus; /* error status */ #endif - u32 bmCtlShadow; // 10 - u32 seqCtlShadow; // 14 - __OSBlockInfo block[2]; // 18 + u32 bmCtlShadow; /* asic bm_ctl(510) register shadow ram */ + u32 seqCtlShadow; /* asic seq_ctl(518) register shadow ram */ + __OSBlockInfo block[2]; /* bolck transfer info */ } __OSTranxInfo; typedef struct OSPiHandle_s { - struct OSPiHandle_s *next; - u8 type; - u8 latency; - u8 pageSize; - u8 relDuration; - u8 pulse; - u8 domain; - u32 baseAddress; - u32 speed; - __OSTranxInfo transferInfo; + struct OSPiHandle_s *next; /* point to next handle on the table */ + u8 type; /* DEVICE_TYPE_BULK for disk */ + u8 latency; /* domain latency */ + u8 pageSize; /* domain page size */ + u8 relDuration; /* domain release duration */ + u8 pulse; /* domain pulse width */ + u8 domain; /* which domain */ + u32 baseAddress; /* Domain address */ + u32 speed; /* for roms only */ + /* The following are "private" elements" */ + __OSTranxInfo transferInfo; /* for disk only */ } OSPiHandle; typedef struct { - u8 type; + u8 type; uintptr_t address; } OSPiInfo; +/* + * Structure for I/O message block + */ typedef struct { - u16 type; - u8 pri; - u8 status; - OSMesgQueue *retQueue; + u16 type; /* Message type */ + u8 pri; /* Message priority (High or Normal) */ + u8 status; /* Return status */ + OSMesgQueue *retQueue; /* Return message queue to notify I/O completion */ } OSIoMesgHdr; typedef struct { - /*0x00*/ OSIoMesgHdr hdr; - /*0x08*/ void *dramAddr; - /*0x0C*/ uintptr_t devAddr; - /*0x10*/ size_t size; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - OSPiHandle *piHandle; // from the official definition + OSIoMesgHdr hdr; /* Message header */ + void *dramAddr; /* RDRAM buffer address (DMA) */ + uintptr_t devAddr; /* Device buffer address (DMA) */ + size_t size; /* DMA transfer size in bytes */ +#if LIBULTRA_VERSION > OS_VER_D + OSPiHandle *piHandle; /* PI device handle */ #endif } OSIoMesg; -/* Definitions */ - -#define OS_READ 0 // device -> RDRAM -#define OS_WRITE 1 // device <- RDRAM - -#define OS_MESG_PRI_NORMAL 0 -#define OS_MESG_PRI_HIGH 1 - -/* Functions */ - -s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, - size_t nbytes, OSMesgQueue *mq); -void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt); -OSMesgQueue *osPiGetCmdQueue(void); -s32 osPiWriteIo(uintptr_t devAddr, u32 data); -s32 osPiReadIo(uintptr_t devAddr, u32 *data); - -s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size); -s32 osEPiRawStartDma(OSPiHandle *piHandle, s32 dir, u32 cart_addr, void *dram_addr, size_t size); +/* + * Structure for device manager block + */ +typedef struct { + s32 active; /* Status flag */ + OSThread *thread; /* Calling thread */ + OSMesgQueue *cmdQueue; /* Command queue */ + OSMesgQueue *evtQueue; /* Event queue */ + OSMesgQueue *acsQueue; /* Access queue */ + /* Raw DMA routine */ + s32 (*dma)(s32, u32, void *, size_t); +#if LIBULTRA_VERSION > OS_VER_D + s32 (*edma)(OSPiHandle *, s32, u32, void *, size_t); +#else + u64 force_align; #endif +} OSDevMgr; + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +/************************************************************************** + * + * Global definitions + * + */ + +/* Flags to indicate direction of data transfer */ + +#define OS_READ 0 /* device -> RDRAM */ +#define OS_WRITE 1 /* device <- RDRAM */ +#define OS_OTHERS 2 /* for Leo disk only */ + +/* + * I/O message types + */ +#define OS_MESG_TYPE_BASE (10) +#define OS_MESG_TYPE_LOOPBACK (OS_MESG_TYPE_BASE + 0) +#define OS_MESG_TYPE_DMAREAD (OS_MESG_TYPE_BASE + 1) +#define OS_MESG_TYPE_DMAWRITE (OS_MESG_TYPE_BASE + 2) +#define OS_MESG_TYPE_VRETRACE (OS_MESG_TYPE_BASE + 3) +#define OS_MESG_TYPE_COUNTER (OS_MESG_TYPE_BASE + 4) +#define OS_MESG_TYPE_EDMAREAD (OS_MESG_TYPE_BASE + 5) +#define OS_MESG_TYPE_EDMAWRITE (OS_MESG_TYPE_BASE + 6) + +/* + * I/O message priority + */ +#define OS_MESG_PRI_NORMAL 0 +#define OS_MESG_PRI_HIGH 1 + +/* + * PI/EPI + */ +#define PI_DOMAIN1 0 +#define PI_DOMAIN2 1 + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + + +/************************************************************************** + * + * Extern variables + * + */ + +extern OSPiHandle *__osPiTable; /* The head of OSPiHandle link list */ +extern OSPiHandle *__osDiskHandle; /* For exceptasm to get disk info*/ + +/************************************************************************** + * + * Function prototypes + * + */ + +extern s32 osPiWriteIo(uintptr_t, u32); +extern s32 osPiReadIo(uintptr_t, u32 *); +extern s32 osPiStartDma(OSIoMesg *, s32, s32, uintptr_t, void *, size_t, OSMesgQueue *); +extern void osCreatePiManager(OSPri, OSMesgQueue *, OSMesg *, s32); + +/* Enhanced PI interface */ + +extern OSPiHandle *osCartRomInit(void); +extern OSPiHandle *osLeoDiskInit(void); +extern OSPiHandle *osDriveRomInit(void); + +extern s32 osEPiDeviceType(OSPiHandle *, OSPiInfo *); +extern s32 osEPiWriteIo(OSPiHandle *, u32 , u32 ); +extern s32 osEPiReadIo(OSPiHandle *, u32 , u32 *); +extern s32 osEPiStartDma(OSPiHandle *, OSIoMesg *, s32); +extern s32 osEPiLinkHandle(OSPiHandle *); + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_PI_H_ */ diff --git a/include/PR/os_reg.h b/include/PR/os_reg.h new file mode 100644 index 00000000..50aa2188 --- /dev/null +++ b/include/PR/os_reg.h @@ -0,0 +1,90 @@ + +/*==================================================================== + * os_reg.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_reg.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:17 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_REG_H_ +#define _OS_REG_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Type definitions + * + */ + + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +/************************************************************************** + * + * Global definitions + * + */ + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + + +/************************************************************************** + * + * Extern variables + * + */ + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* Miscellaneous operations */ + +extern u32 osGetCount(void); + + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_REG_H_ */ diff --git a/include/PR/os_system.h b/include/PR/os_system.h new file mode 100644 index 00000000..5128f204 --- /dev/null +++ b/include/PR/os_system.h @@ -0,0 +1,103 @@ + +/*==================================================================== + * os_system.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_system.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:18 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_SYSTEM_H_ +#define _OS_SYSTEM_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "ultratypes.h" +#include "os_version.h" + +/* + * Values for osTvType + */ +#define OS_TV_PAL 0 +#define OS_TV_NTSC 1 +#define OS_TV_MPAL 2 + +/* + * Size of buffer the retains contents after NMI + */ +#define OS_APP_NMI_BUFSIZE 64 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +extern s32 osRomType; /* Bulk or cartridge ROM. 0=cartridge 1=bulk */ +extern void *osRomBase; /* Rom base address of the game image */ +extern s32 osTvType; /* 0 = PAL, 1 = NTSC, 2 = MPAL */ +extern s32 osResetType; /* 0 = cold reset, 1 = NMI */ +extern s32 osCicId; +extern s32 osVersion; +extern u32 osMemSize; /* Memory Size */ +extern s32 osAppNMIBuffer[OS_APP_NMI_BUFSIZE/sizeof(s32)]; + +/* + * CPU counter increments at 3/4 of bus clock rate: + * + * Bus Clock Proc Clock Counter (1/2 Proc Clock) + * --------- ---------- ------------------------ + * 62.5 Mhz 93.75 Mhz 46.875 Mhz + */ +extern u64 osClockRate; + +extern OSIntMask __OSGlobalIntMask; /* global interrupt mask */ + +#ifdef BBPLAYER +void osInitialize(void); +void __osInitialize_common(void); +void __osInitialize_autodetect(void); +#else +#if LIBULTRA_VERSION >= OS_VER_K +void __osInitialize_common(void); +void __osInitialize_autodetect(void); +#define osInitialize() \ + __osInitialize_common(); \ + __osInitialize_autodetect() +#else +void osInitialize(void); +#define __osInitialize_common osInitialize +#endif +#endif + +extern void osExit(void); +extern u32 osGetMemSize(void); + +/* pre-NMI */ +extern s32 osAfterPreNMI(void); + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_SYSTEM_H_ */ diff --git a/include/PR/os_thread.h b/include/PR/os_thread.h index c07a5745..380ff608 100644 --- a/include/PR/os_thread.h +++ b/include/PR/os_thread.h @@ -66,13 +66,13 @@ typedef struct OSThread_s /* Functions */ -void osCreateThread(OSThread *thread, OSId id, void (*entry)(void *), - void *arg, void *sp, OSPri pri); -OSId osGetThreadId(OSThread *thread); -OSPri osGetThreadPri(OSThread *thread); -void osSetThreadPri(OSThread *thread, OSPri pri); -void osStartThread(OSThread *thread); -void osStopThread(OSThread *thread); +void osCreateThread(OSThread *, OSId, void (*)(void *), void *, void *, OSPri); +void osYieldThread(void); +OSId osGetThreadId(OSThread *); +OSPri osGetThreadPri(OSThread *); +void osSetThreadPri(OSThread *, OSPri); +void osStartThread(OSThread *); +void osStopThread(OSThread *); #endif diff --git a/include/PR/os_time.h b/include/PR/os_time.h index 878d13fd..4b5fc7e1 100644 --- a/include/PR/os_time.h +++ b/include/PR/os_time.h @@ -1,27 +1,113 @@ -#ifndef _ULTRA64_TIME_H_ -#define _ULTRA64_TIME_H_ + +/*==================================================================== + * os_time.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_time.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:19 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_TIME_H_ +#define _OS_TIME_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif #include -#include +#include "os_message.h" -/* Types */ -typedef struct OSTimer_str -{ - struct OSTimer_str *next; - struct OSTimer_str *prev; - u64 interval; - u64 remaining; - OSMesgQueue *mq; - OSMesg msg; +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Type definitions + * + */ + +/* + * Structure for time value + */ +typedef u64 OSTime; + +/* + * Structure for interval timer + */ +typedef struct OSTimer_s { + struct OSTimer_s *next; /* point to next timer in list */ + struct OSTimer_s *prev; /* point to previous timer in list */ + OSTime interval; /* duration set by user */ + OSTime value; /* time remaining before */ + /* timer fires */ + OSMesgQueue *mq; /* Message Queue */ + OSMesg msg; /* Message to send */ } OSTimer; -typedef u64 OSTime; -/* Functions */ +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ -OSTime osGetTime(void); -void osSetTime(OSTime time); -u32 osSetTimer(OSTimer *, OSTime, OSTime, OSMesgQueue *, OSMesg); +/************************************************************************** + * + * Global definitions + * + */ + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + + +/************************************************************************** + * + * Extern variables + * + */ + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* Timer interface */ + +extern OSTime osGetTime(void); +extern void osSetTime(OSTime); +extern u32 osSetTimer(OSTimer *, OSTime, OSTime, OSMesgQueue *, OSMesg); +extern int osStopTimer(OSTimer *); + + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} #endif + +#endif /* !_OS_TIME_H_ */ diff --git a/include/PR/os_version.h b/include/PR/os_version.h new file mode 100644 index 00000000..f437a7e4 --- /dev/null +++ b/include/PR/os_version.h @@ -0,0 +1,23 @@ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. + + $RCSfile: os_version.h,v $ + $Revision: 1.2 $ + $Date: 1999/06/17 01:33:01 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_VERSION_H_ +#define _OS_VERSION_H_ + +#define OS_VER_D 1 +#define OS_VER_E 2 +#define OS_VER_F 3 +#define OS_VER_G 4 +#define OS_VER_H 5 +#define OS_VER_I 6 +#define OS_VER_J 7 +#define OS_VER_K 8 +#define OS_VER_L 9 + +#endif /* !_OS_VERSION_H_ */ diff --git a/include/PR/os_vi.h b/include/PR/os_vi.h index d27c5c55..787aa8a9 100644 --- a/include/PR/os_vi.h +++ b/include/PR/os_vi.h @@ -1,92 +1,100 @@ -#ifndef _ULTRA64_VI_H_ -#define _ULTRA64_VI_H_ + +/*==================================================================== + * os_vi.h + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +/*---------------------------------------------------------------------* + Copyright (C) 1998 Nintendo. (Originated by SGI) + + $RCSfile: os_vi.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:20 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_VI_H_ +#define _OS_VI_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif #include -#include +#include "os_thread.h" +#include "os_message.h" +#include "os_version.h" -//TODO: figure out what this is -#define VI_STATE_01 0x01 -#define VI_STATE_XSCALE_UPDATED 0x02 -#define VI_STATE_YSCALE_UPDATED 0x04 -#define VI_STATE_08 0x08 //related to control regs changing -#define VI_STATE_10 0x10 //swap buffer -#define VI_STATE_BLACK 0x20 //probably related to a black screen -#define VI_STATE_REPEATLINE 0x40 //repeat line? -#define VI_STATE_FADE 0x80 //fade +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) -/* Ultra64 Video Interface */ - - -/* Special Features */ -#define OS_VI_GAMMA_ON 0x0001 -#define OS_VI_GAMMA_OFF 0x0002 -#define OS_VI_GAMMA_DITHER_ON 0x0004 -#define OS_VI_GAMMA_DITHER_OFF 0x0008 -#define OS_VI_DIVOT_ON 0x0010 -#define OS_VI_DIVOT_OFF 0x0020 -#define OS_VI_DITHER_FILTER_ON 0x0040 -#define OS_VI_DITHER_FILTER_OFF 0x0080 - -#define OS_VI_GAMMA 0x08 -#define OS_VI_GAMMA_DITHER 0x04 -#define OS_VI_DIVOT 0x10 -#define OS_VI_DITHER_FILTER 0x10000 -#define OS_VI_UNK200 0x200 -#define OS_VI_UNK100 0x100 - - -/* Types */ +/************************************************************************** + * + * Type definitions + * + */ +/* + * Structure to store VI register values that remain the same between 2 fields + */ typedef struct { - u32 ctrl; - u32 width; - u32 burst; - u32 vSync; - u32 hSync; - u32 leap; - u32 hStart; - u32 xScale; - u32 vCurrent; + u32 ctrl; + u32 width; + u32 burst; + u32 vSync; + u32 hSync; + u32 leap; + u32 hStart; + u32 xScale; + u32 vCurrent; } OSViCommonRegs; + +/* + * Structure to store VI register values that change between fields + */ typedef struct { - u32 origin; - u32 yScale; - u32 vStart; - u32 vBurst; - u32 vIntr; + u32 origin; + u32 yScale; + u32 vStart; + u32 vBurst; + u32 vIntr; } OSViFieldRegs; + +/* + * Structure for VI mode + */ typedef struct { - u8 type; - OSViCommonRegs comRegs; - OSViFieldRegs fldRegs[2]; + u8 type; /* Mode type */ + OSViCommonRegs comRegs; /* Common registers for both fields */ + OSViFieldRegs fldRegs[2]; /* Registers for Field 1 & 2 */ } OSViMode; -typedef struct { - /* 0x00 */ u16 unk00; //some kind of flags. swap buffer sets to 0x10 - /* 0x02 */ u16 retraceCount; - /* 0x04 */ void* buffer; - /* 0x08 */ OSViMode *modep; - /* 0x0c */ u32 features; - /* 0x10 */ OSMesgQueue *mq; - /* 0x14 */ OSMesg *msg; - /* 0x18 */ u32 unk18; - /* 0x1c */ u32 unk1c; - /* 0x20 */ u32 unk20; - /* 0x24 */ f32 unk24; - /* 0x28 */ u16 unk28; - /* 0x2c */ u32 unk2c; -} OSViContext; - -void osCreateViManager(OSPri pri); -void osViSetMode(OSViMode *mode); -void osViSetEvent(OSMesgQueue *mq, OSMesg msg, u32 retraceCount); -void osViBlack(u8 active); -void osViSetSpecialFeatures(u32 func); -void osViSwapBuffer(void *vaddr); +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ +/************************************************************************** + * + * Global definitions + * + */ +/* + * Video Interface (VI) mode type + */ #define OS_VI_NTSC_LPN1 0 /* NTSC */ #define OS_VI_NTSC_LPF1 1 #define OS_VI_NTSC_LAN1 2 @@ -117,7 +125,193 @@ void osViSwapBuffer(void *vaddr); #define OS_VI_PAL_HPN2 26 #define OS_VI_PAL_HPF2 27 -extern OSViMode osViModeTable[]; /* Global VI mode table */ +#define OS_VI_MPAL_LPN1 28 /* MPAL - mainly Brazil */ +#define OS_VI_MPAL_LPF1 29 +#define OS_VI_MPAL_LAN1 30 +#define OS_VI_MPAL_LAF1 31 +#define OS_VI_MPAL_LPN2 32 +#define OS_VI_MPAL_LPF2 33 +#define OS_VI_MPAL_LAN2 34 +#define OS_VI_MPAL_LAF2 35 +#define OS_VI_MPAL_HPN1 36 +#define OS_VI_MPAL_HPF1 37 +#define OS_VI_MPAL_HAN1 38 +#define OS_VI_MPAL_HAF1 39 +#define OS_VI_MPAL_HPN2 40 +#define OS_VI_MPAL_HPF2 41 +#define OS_VI_FPAL_LPN1 42 /* FPAL - Full screen PAL */ +#define OS_VI_FPAL_LPF1 43 +#define OS_VI_FPAL_LAN1 44 +#define OS_VI_FPAL_LAF1 45 +#define OS_VI_FPAL_LPN2 46 +#define OS_VI_FPAL_LPF2 47 +#define OS_VI_FPAL_LAN2 48 +#define OS_VI_FPAL_LAF2 49 +#define OS_VI_FPAL_HPN1 50 +#define OS_VI_FPAL_HPF1 51 +#define OS_VI_FPAL_HAN1 52 +#define OS_VI_FPAL_HAF1 53 +#define OS_VI_FPAL_HPN2 54 +#define OS_VI_FPAL_HPF2 55 + +/* + * Video Interface (VI) special features + */ +#define OS_VI_GAMMA_ON 0x0001 +#define OS_VI_GAMMA_OFF 0x0002 +#define OS_VI_GAMMA_DITHER_ON 0x0004 +#define OS_VI_GAMMA_DITHER_OFF 0x0008 +#define OS_VI_DIVOT_ON 0x0010 +#define OS_VI_DIVOT_OFF 0x0020 +#define OS_VI_DITHER_FILTER_ON 0x0040 +#define OS_VI_DITHER_FILTER_OFF 0x0080 + +/* + * Video Interface (VI) mode attribute bit + */ +#define OS_VI_BIT_NONINTERLACE 0x0001 /* lo-res */ +#define OS_VI_BIT_INTERLACE 0x0002 /* lo-res */ +#define OS_VI_BIT_NORMALINTERLACE 0x0004 /* hi-res */ +#define OS_VI_BIT_DEFLICKINTERLACE 0x0008 /* hi-res */ +#define OS_VI_BIT_ANTIALIAS 0x0010 +#define OS_VI_BIT_POINTSAMPLE 0x0020 +#define OS_VI_BIT_16PIXEL 0x0040 +#define OS_VI_BIT_32PIXEL 0x0080 +#define OS_VI_BIT_LORES 0x0100 +#define OS_VI_BIT_HIRES 0x0200 +#define OS_VI_BIT_NTSC 0x0400 +#define OS_VI_BIT_PAL 0x0800 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + +#define OS_VI_BURST(hsync_width, color_width, vsync_width, color_start) \ + (hsync_width | (color_width << 8) | (vsync_width << 16) | (color_start << 20)) +#define OS_VI_WIDTH(v) v +#define OS_VI_VSYNC(v) v +#define OS_VI_HSYNC(duration, leap) (duration | (leap << 16)) +#define OS_VI_LEAP(upper, lower) ((upper << 16) | lower) +#define OS_VI_START(start, end) ((start << 16) | end) + +#define OS_VI_FTOFIX(val, i, f) ((u32)(val * (f32)(1 << f)) & ((1 << (i + f)) - 1)) + +#define OS_VI_F210(val) OS_VI_FTOFIX(val, 2, 10) +#define OS_VI_SCALE(scaleup, off) (OS_VI_F210((1.0f / (f32)scaleup)) | (OS_VI_F210((f32)off) << 16)) + +#define OS_VI_VCURRENT(v) v //seemingly unused +#define OS_VI_ORIGIN(v) v +#define OS_VI_VINTR(v) v +#define OS_VI_HSTART OS_VI_START + +#if LIBULTRA_VERSION > OS_VER_F + +#define OS_VI_BURST_CW_PAL 30 +#define OS_VI_BURST_CS_PAL 69 +#define OS_VI_HSYNC_LEAP_PAL 23 +#define OS_VI_LEAP_LOWER_PAL 3181 + +#else + +#define OS_VI_BURST_CW_PAL 35 +#define OS_VI_BURST_CS_PAL 64 +#define OS_VI_HSYNC_LEAP_PAL 21 +#define OS_VI_LEAP_LOWER_PAL 3182 #endif + +/************************************************************************** + * + * Extern variables + * + */ + +extern OSViMode osViModeTable[]; /* Global VI mode table */ + +extern OSViMode osViModeNtscLpn1; /* Individual VI NTSC modes */ +extern OSViMode osViModeNtscLpf1; +extern OSViMode osViModeNtscLan1; +extern OSViMode osViModeNtscLaf1; +extern OSViMode osViModeNtscLpn2; +extern OSViMode osViModeNtscLpf2; +extern OSViMode osViModeNtscLan2; +extern OSViMode osViModeNtscLaf2; +extern OSViMode osViModeNtscHpn1; +extern OSViMode osViModeNtscHpf1; +extern OSViMode osViModeNtscHan1; +extern OSViMode osViModeNtscHaf1; +extern OSViMode osViModeNtscHpn2; +extern OSViMode osViModeNtscHpf2; + +extern OSViMode osViModePalLpn1; /* Individual VI PAL modes */ +extern OSViMode osViModePalLpf1; +extern OSViMode osViModePalLan1; +extern OSViMode osViModePalLaf1; +extern OSViMode osViModePalLpn2; +extern OSViMode osViModePalLpf2; +extern OSViMode osViModePalLan2; +extern OSViMode osViModePalLaf2; +extern OSViMode osViModePalHpn1; +extern OSViMode osViModePalHpf1; +extern OSViMode osViModePalHan1; +extern OSViMode osViModePalHaf1; +extern OSViMode osViModePalHpn2; +extern OSViMode osViModePalHpf2; + +extern OSViMode osViModeMpalLpn1; /* Individual VI MPAL modes */ +extern OSViMode osViModeMpalLpf1; +extern OSViMode osViModeMpalLan1; +extern OSViMode osViModeMpalLaf1; +extern OSViMode osViModeMpalLpn2; +extern OSViMode osViModeMpalLpf2; +extern OSViMode osViModeMpalLan2; +extern OSViMode osViModeMpalLaf2; +extern OSViMode osViModeMpalHpn1; +extern OSViMode osViModeMpalHpf1; +extern OSViMode osViModeMpalHan1; +extern OSViMode osViModeMpalHaf1; +extern OSViMode osViModeMpalHpn2; +extern OSViMode osViModeMpalHpf2; + +extern OSViMode osViModeFpalLpn1; /* Individual VI FPAL modes */ +extern OSViMode osViModeFpalLpf1; +extern OSViMode osViModeFpalLan1; +extern OSViMode osViModeFpalLaf1; +extern OSViMode osViModeFpalLpn2; +extern OSViMode osViModeFpalLpf2; +extern OSViMode osViModeFpalLan2; +extern OSViMode osViModeFpalLaf2; +extern OSViMode osViModeFpalHpn1; +extern OSViMode osViModeFpalHpf1; +extern OSViMode osViModeFpalHan1; +extern OSViMode osViModeFpalHaf1; +extern OSViMode osViModeFpalHpn2; +extern OSViMode osViModeFpalHpf2; + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* Video interface (Vi) */ +extern void osViSetSpecialFeatures(u32); +extern void osViSetMode(OSViMode *); +extern void osViSetEvent(OSMesgQueue *, OSMesg, u32); +extern void osViSwapBuffer(void *); +extern void osViBlack(u8); +extern void osCreateViManager(OSPri); + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_VI_H_ */ diff --git a/include/PR/rcp.h b/include/PR/rcp.h index 022943e3..51b0414a 100644 --- a/include/PR/rcp.h +++ b/include/PR/rcp.h @@ -18,129 +18,106 @@ * File: rcp.h * * This file contains register and bit definitions for RCP memory map. - * $Revision: 1.20 $ - * $Date: 1997/07/23 08:35:21 $ - * $Source: /disk6/Master/cvsmdev2/PR/include/rcp.h,v $ + * $Revision: 1.22 $ + * $Date: 1999/05/20 03:01:49 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/rcp.h,v $ * **************************************************************************/ -#include -#include +#include "R4300.h" +#include "ultratypes.h" -/********************************************************************** - * - * Here is a quick overview of the RCP memory map: - * - -0x0000_0000 .. 0x03ef_ffff RDRAM memory -0x03f0_0000 .. 0x03ff_ffff RDRAM registers - - RCP registers (see below) -0x0400_0000 .. 0x040f_ffff SP registers -0x0410_0000 .. 0x041f_ffff DP command registers -0x0420_0000 .. 0x042f_ffff DP span registers -0x0430_0000 .. 0x043f_ffff MI registers -0x0440_0000 .. 0x044f_ffff VI registers -0x0450_0000 .. 0x045f_ffff AI registers -0x0460_0000 .. 0x046f_ffff PI registers -0x0470_0000 .. 0x047f_ffff RI registers -0x0480_0000 .. 0x048f_ffff SI registers -0x0490_0000 .. 0x04ff_ffff unused - -0x0500_0000 .. 0x05ff_ffff cartridge domain 2 -0x0600_0000 .. 0x07ff_ffff cartridge domain 1 -0x0800_0000 .. 0x0fff_ffff cartridge domain 2 -0x1000_0000 .. 0x1fbf_ffff cartridge domain 1 - -0x1fc0_0000 .. 0x1fc0_07bf PIF Boot Rom (1984 bytes) -0x1fc0_07c0 .. 0x1fc0_07ff PIF (JoyChannel) RAM (64 bytes) -0x1fc0_0800 .. 0x1fcf_ffff Reserved -0x1fd0_0000 .. 0x7fff_ffff cartridge domain 1 -0x8000_0000 .. 0xffff_ffff external SysAD device - -The Indy development board use cartridge domain 1: -0x1000_0000 .. 0x10ff_ffff RAMROM -0x1800_0000 .. 0x1800_0003 GIO interrupt (6 bits valid in 4 bytes) -0x1800_0400 .. 0x1800_0403 GIO sync (6 bits valid in 4 bytes) -0x1800_0800 .. 0x1800_0803 CART interrupt (6 bits valid in 4 bytes) - - - -**************************************************************************/ - - -/************************************************************************* - * RDRAM Memory (Assumes that maximum size is 4 MB) +/** + * RCP memory map overview: + * + * 0x0000_0000 .. 0x03ef_ffff RDRAM memory + * 0x03f0_0000 .. 0x03ff_ffff RDRAM registers + * + * 0x0400_0000 .. 0x0400_2000 SP memory + * 0x0404_0000 .. 0x040f_ffff SP registers + * 0x0410_0000 .. 0x041f_ffff DP command registers + * 0x0420_0000 .. 0x042f_ffff DP span registers + * 0x0430_0000 .. 0x043f_ffff MI registers + * 0x0440_0000 .. 0x044f_ffff VI registers + * 0x0450_0000 .. 0x045f_ffff AI registers + * 0x0460_0000 .. 0x046f_ffff PI registers + * 0x0470_0000 .. 0x047f_ffff RI registers + * 0x0480_0000 .. 0x048f_ffff SI registers + * 0x0490_0000 .. 0x04ff_ffff unused + * + * 0x0500_0000 .. 0x05ff_ffff cartridge domain 2 + * 0x0600_0000 .. 0x07ff_ffff cartridge domain 1 + * 0x0800_0000 .. 0x0fff_ffff cartridge domain 2 + * 0x1000_0000 .. 0x1fbf_ffff cartridge domain 1 + * + * 0x1fc0_0000 .. 0x1fc0_07bf PIF Boot Rom (1984 bytes) + * 0x1fc0_07c0 .. 0x1fc0_07ff PIF (JoyChannel) RAM (64 bytes) + * 0x1fc0_0800 .. 0x1fcf_ffff Reserved + * 0x1fd0_0000 .. 0x7fff_ffff cartridge domain 1 + * 0x8000_0000 .. 0xffff_ffff external SysAD device */ -#define RDRAM_0_START 0x00000000 -#define RDRAM_0_END 0x001FFFFF -#define RDRAM_1_START 0x00200000 -#define RDRAM_1_END 0x003FFFFF -#define RDRAM_START RDRAM_0_START -#define RDRAM_END RDRAM_1_END - - -/************************************************************************* - * Address predicates +/** + * RDRAM memory */ -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) -#define IS_RDRAM(x) ((unsigned)(x) >= RDRAM_START && \ - (unsigned)(x) < RDRAM_END) -#endif +#define RDRAM_0_START 0x00000000 +#define RDRAM_0_END 0x001FFFFF +#define RDRAM_1_START 0x00200000 +#define RDRAM_1_END 0x003FFFFF -/************************************************************************* - * RDRAM Registers (0x03f0_0000 .. 0x03ff_ffff) +#define RDRAM_START RDRAM_0_START +#define RDRAM_END RDRAM_1_END + +/** + * RDRAM registers */ -#define RDRAM_BASE_REG 0x03F00000 +#define RDRAM_BASE_REG 0x03F00000 -#define RDRAM_CONFIG_REG (RDRAM_BASE_REG+0x00) -#define RDRAM_DEVICE_TYPE_REG (RDRAM_BASE_REG+0x00) -#define RDRAM_DEVICE_ID_REG (RDRAM_BASE_REG+0x04) -#define RDRAM_DELAY_REG (RDRAM_BASE_REG+0x08) -#define RDRAM_MODE_REG (RDRAM_BASE_REG+0x0c) -#define RDRAM_REF_INTERVAL_REG (RDRAM_BASE_REG+0x10) -#define RDRAM_REF_ROW_REG (RDRAM_BASE_REG+0x14) -#define RDRAM_RAS_INTERVAL_REG (RDRAM_BASE_REG+0x18) -#define RDRAM_MIN_INTERVAL_REG (RDRAM_BASE_REG+0x1c) -#define RDRAM_ADDR_SELECT_REG (RDRAM_BASE_REG+0x20) -#define RDRAM_DEVICE_MANUF_REG (RDRAM_BASE_REG+0x24) +#define RDRAM_CONFIG_REG (RDRAM_BASE_REG + 0x00) +#define RDRAM_DEVICE_TYPE_REG (RDRAM_BASE_REG + 0x00) +#define RDRAM_DEVICE_ID_REG (RDRAM_BASE_REG + 0x04) +#define RDRAM_DELAY_REG (RDRAM_BASE_REG + 0x08) +#define RDRAM_MODE_REG (RDRAM_BASE_REG + 0x0c) +#define RDRAM_REF_INTERVAL_REG (RDRAM_BASE_REG + 0x10) +#define RDRAM_REF_ROW_REG (RDRAM_BASE_REG + 0x14) +#define RDRAM_RAS_INTERVAL_REG (RDRAM_BASE_REG + 0x18) +#define RDRAM_MIN_INTERVAL_REG (RDRAM_BASE_REG + 0x1c) +#define RDRAM_ADDR_SELECT_REG (RDRAM_BASE_REG + 0x20) +#define RDRAM_DEVICE_MANUF_REG (RDRAM_BASE_REG + 0x24) -#define RDRAM_0_DEVICE_ID 0 -#define RDRAM_1_DEVICE_ID 1 +#define RDRAM_0_DEVICE_ID 0 +#define RDRAM_1_DEVICE_ID 1 -#define RDRAM_RESET_MODE 0 -#define RDRAM_ACTIVE_MODE 1 -#define RDRAM_STANDBY_MODE 2 +#define RDRAM_RESET_MODE 0 +#define RDRAM_ACTIVE_MODE 1 +#define RDRAM_STANDBY_MODE 2 -#define RDRAM_LENGTH (2*512*2048) -#define RDRAM_0_BASE_ADDRESS (RDRAM_0_DEVICE_ID*RDRAM_LENGTH) -#define RDRAM_1_BASE_ADDRESS (RDRAM_1_DEVICE_ID*RDRAM_LENGTH) +#define RDRAM_LENGTH (2 * 512 * 2048) +#define RDRAM_0_BASE_ADDRESS (RDRAM_0_DEVICE_ID * RDRAM_LENGTH) +#define RDRAM_1_BASE_ADDRESS (RDRAM_1_DEVICE_ID * RDRAM_LENGTH) -#define RDRAM_0_CONFIG 0x00000 -#define RDRAM_1_CONFIG 0x00400 -#define RDRAM_GLOBAL_CONFIG 0x80000 +#define RDRAM_0_CONFIG 0x00000 +#define RDRAM_1_CONFIG 0x00400 +#define RDRAM_GLOBAL_CONFIG 0x80000 - -/************************************************************************* +/** * PIF Physical memory map (total size = 2 KB) * - * Size Description Mode - * 1FC007FF +-------+-----------------+-----+ - * | 64 B | JoyChannel RAM | R/W | - * 1FC007C0 +-------+-----------------+-----+ - * |1984 B | Boot ROM | * | * = Reserved - * 1FC00000 +-------+-----------------+-----+ - * + * Size Description Mode + * 1FC007FF +-------+-----------------+-----+ + * | 64 B | JoyChannel RAM | R/W | + * 1FC007C0 +-------+-----------------+-----+ + * |1984 B | Boot ROM | * | * = Reserved + * 1FC00000 +-------+-----------------+-----+ */ -#define PIF_ROM_START 0x1FC00000 -#define PIF_ROM_END 0x1FC007BF -#define PIF_RAM_START 0x1FC007C0 -#define PIF_RAM_END 0x1FC007FF +#define PIF_ROM_START 0x1FC00000 +#define PIF_ROM_END 0x1FC007BF +#define PIF_RAM_START 0x1FC007C0 +#define PIF_RAM_END 0x1FC007FF -/************************************************************************* +/** * Controller channel * Each game controller channel has 4 error bits that are defined in bit 6-7 of * the Rx and Tx data size area bytes. Programmers need to clear these bits @@ -154,700 +131,694 @@ The Indy development board use cartridge domain 1: #define CHNL_ERR_MASK 0xC0 /* Bit 6-7: channel errors */ -/************************************************************************* +/** * External device info */ #define DEVICE_TYPE_CART 0 /* ROM cartridge */ #define DEVICE_TYPE_BULK 1 /* ROM bulk */ #define DEVICE_TYPE_64DD 2 /* 64 Disk Drive */ #define DEVICE_TYPE_SRAM 3 /* SRAM */ +/* 4-6 are reserved */ #define DEVICE_TYPE_INIT 7 /* initial value */ +/* 8-14 are reserved */ -/************************************************************************* - * SP Memory +/** + * Signal Processor (SP) Memory */ -#define SP_DMEM_START 0x04000000 /* read/write */ -#define SP_DMEM_END 0x04000FFF -#define SP_IMEM_START 0x04001000 /* read/write */ -#define SP_IMEM_END 0x04001FFF +#define SP_DMEM_START 0x04000000 +#define SP_DMEM_END 0x04000FFF +#define SP_IMEM_START 0x04001000 +#define SP_IMEM_END 0x04001FFF -/************************************************************************* - * SP CP0 Registers +/** + * Signal Processor (SP) CP0 Registers */ -#define SP_BASE_REG 0x04040000 +#define SP_BASE_REG 0x04040000 + +/* SP memory address (R/W): [11:0] DMEM/IMEM address, [12] 0=DMEM,1=IMEM */ +#define SP_MEM_ADDR_REG (SP_BASE_REG + 0x00) -/* SP memory address (R/W): [11:0] DMEM/IMEM address; [12] 0=DMEM,1=IMEM */ -#define SP_MEM_ADDR_REG (SP_BASE_REG+0x00) /* Master */ - /* SP DRAM DMA address (R/W): [23:0] RDRAM address */ -#define SP_DRAM_ADDR_REG (SP_BASE_REG+0x04) /* Slave */ +#define SP_DRAM_ADDR_REG (SP_BASE_REG + 0x04) -/* SP read DMA length (R/W): [11:0] length, [19:12] count, [31:20] skip */ -/* direction: I/DMEM <- RDRAM */ -#define SP_RD_LEN_REG (SP_BASE_REG+0x08) /* R/W: read len */ +/* SP read DMA length (R/W): [11:0] length, [19:12] count, [31:20] skip; RDRAM -> I/DMEM */ +#define SP_RD_LEN_REG (SP_BASE_REG + 0x08) -/* SP write DMA length (R/W): [11:0] length, [19:12] count, [31:20] skip */ -/* direction: I/DMEM -> RDRAM */ -#define SP_WR_LEN_REG (SP_BASE_REG+0x0C) /* R/W: write len */ +/* SP write DMA length (R/W): [11:0] length, [19:12] count, [31:20] skip; I/DMEM -> RDRAM */ +#define SP_WR_LEN_REG (SP_BASE_REG + 0x0C) /* SP status (R/W): [14:0] valid bits; see below for write/read mode */ -#define SP_STATUS_REG (SP_BASE_REG+0x10) +#define SP_STATUS_REG (SP_BASE_REG + 0x10) -/* SP DMA full (R): [0] valid bit; dma full */ -#define SP_DMA_FULL_REG (SP_BASE_REG+0x14) +/* SP DMA full (R): [0] dma full */ +#define SP_DMA_FULL_REG (SP_BASE_REG + 0x14) -/* SP DMA busy (R): [0] valid bit; dma busy */ -#define SP_DMA_BUSY_REG (SP_BASE_REG+0x18) +/* SP DMA busy (R): [0] dma busy */ +#define SP_DMA_BUSY_REG (SP_BASE_REG + 0x18) -/* SP semaphore (R/W): Read: [0] semaphore flag (set on read) */ -/* Write: [] clear semaphore flag */ -#define SP_SEMAPHORE_REG (SP_BASE_REG+0x1C) +/* SP semaphore (R/W): Read: [0] acquire semaphore; Write: [] release semaphore */ +#define SP_SEMAPHORE_REG (SP_BASE_REG + 0x1C) /* SP PC (R/W): [11:0] program counter */ -#define SP_PC_REG 0x04080000 +#define SP_PC_REG 0x04080000 -/* SP MEM address: bit 12 specifies if address is IMEM or DMEM */ -#define SP_DMA_DMEM 0x0000 /* Bit 12: 0=DMEM, 1=IMEM */ -#define SP_DMA_IMEM 0x1000 /* Bit 12: 0=DMEM, 1=IMEM */ +/** + * SP_MEM_ADDR_REG: bit 12 + */ +#define SP_DMA_DMEM (0 << 12) +#define SP_DMA_IMEM (1 << 12) + +/** + * SP_STATUS_REG: write bits + */ +#define SP_CLR_HALT (1 << 0) /* clear halt */ +#define SP_SET_HALT (1 << 1) /* set halt */ +#define SP_CLR_BROKE (1 << 2) /* clear broke */ +#define SP_CLR_INTR (1 << 3) /* clear interrupt */ +#define SP_SET_INTR (1 << 4) /* set interrupt */ +#define SP_CLR_SSTEP (1 << 5) /* clear sstep */ +#define SP_SET_SSTEP (1 << 6) /* set sstep */ +#define SP_CLR_INTR_BREAK (1 << 7) /* clear interrupt on break */ +#define SP_SET_INTR_BREAK (1 << 8) /* set interrupt on break */ +#define SP_CLR_SIG0 (1 << 9) /* clear signal 0 */ +#define SP_SET_SIG0 (1 << 10) /* set signal 0 */ +#define SP_CLR_SIG1 (1 << 11) /* clear signal 1 */ +#define SP_SET_SIG1 (1 << 12) /* set signal 1 */ +#define SP_CLR_SIG2 (1 << 13) /* clear signal 2 */ +#define SP_SET_SIG2 (1 << 14) /* set signal 2 */ +#define SP_CLR_SIG3 (1 << 15) /* clear signal 3 */ +#define SP_SET_SIG3 (1 << 16) /* set signal 3 */ +#define SP_CLR_SIG4 (1 << 17) /* clear signal 4 */ +#define SP_SET_SIG4 (1 << 18) /* set signal 4 */ +#define SP_CLR_SIG5 (1 << 19) /* clear signal 5 */ +#define SP_SET_SIG5 (1 << 20) /* set signal 5 */ +#define SP_CLR_SIG6 (1 << 21) /* clear signal 6 */ +#define SP_SET_SIG6 (1 << 22) /* set signal 6 */ +#define SP_CLR_SIG7 (1 << 23) /* clear signal 7 */ +#define SP_SET_SIG7 (1 << 24) /* set signal 7 */ /* - * Values to clear/set bit in status reg (SP_STATUS_REG - write) + * SP_STATUS_REG: read bits */ -#define SP_CLR_HALT 0x00001 /* Bit 0: clear halt */ -#define SP_SET_HALT 0x00002 /* Bit 1: set halt */ -#define SP_CLR_BROKE 0x00004 /* Bit 2: clear broke */ -#define SP_CLR_INTR 0x00008 /* Bit 3: clear intr */ -#define SP_SET_INTR 0x00010 /* Bit 4: set intr */ -#define SP_CLR_SSTEP 0x00020 /* Bit 5: clear sstep */ -#define SP_SET_SSTEP 0x00040 /* Bit 6: set sstep */ -#define SP_CLR_INTR_BREAK 0x00080 /* Bit 7: clear intr on break */ -#define SP_SET_INTR_BREAK 0x00100 /* Bit 8: set intr on break */ -#define SP_CLR_SIG0 0x00200 /* Bit 9: clear signal 0 */ -#define SP_SET_SIG0 0x00400 /* Bit 10: set signal 0 */ -#define SP_CLR_SIG1 0x00800 /* Bit 11: clear signal 1 */ -#define SP_SET_SIG1 0x01000 /* Bit 12: set signal 1 */ -#define SP_CLR_SIG2 0x02000 /* Bit 13: clear signal 2 */ -#define SP_SET_SIG2 0x04000 /* Bit 14: set signal 2 */ -#define SP_CLR_SIG3 0x08000 /* Bit 15: clear signal 3 */ -#define SP_SET_SIG3 0x10000 /* Bit 16: set signal 3 */ -#define SP_CLR_SIG4 0x20000 /* Bit 17: clear signal 4 */ -#define SP_SET_SIG4 0x40000 /* Bit 18: set signal 4 */ -#define SP_CLR_SIG5 0x80000 /* Bit 19: clear signal 5 */ -#define SP_SET_SIG5 0x100000 /* Bit 20: set signal 5 */ -#define SP_CLR_SIG6 0x200000 /* Bit 21: clear signal 6 */ -#define SP_SET_SIG6 0x400000 /* Bit 22: set signal 6 */ -#define SP_CLR_SIG7 0x800000 /* Bit 23: clear signal 7 */ -#define SP_SET_SIG7 0x1000000 /* Bit 24: set signal 7 */ - -/* - * Patterns to interpret status reg (SP_STATUS_REG - read) - */ -#define SP_STATUS_HALT 0x001 /* Bit 0: halt */ -#define SP_STATUS_BROKE 0x002 /* Bit 1: broke */ -#define SP_STATUS_DMA_BUSY 0x004 /* Bit 2: dma busy */ -#define SP_STATUS_DMA_FULL 0x008 /* Bit 3: dma full */ -#define SP_STATUS_IO_FULL 0x010 /* Bit 4: io full */ -#define SP_STATUS_SSTEP 0x020 /* Bit 5: single step */ -#define SP_STATUS_INTR_BREAK 0x040 /* Bit 6: interrupt on break */ -#define SP_STATUS_SIG0 0x080 /* Bit 7: signal 0 set */ -#define SP_STATUS_SIG1 0x100 /* Bit 8: signal 1 set */ -#define SP_STATUS_SIG2 0x200 /* Bit 9: signal 2 set */ -#define SP_STATUS_SIG3 0x400 /* Bit 10: signal 3 set */ -#define SP_STATUS_SIG4 0x800 /* Bit 11: signal 4 set */ -#define SP_STATUS_SIG5 0x1000 /* Bit 12: signal 5 set */ -#define SP_STATUS_SIG6 0x2000 /* Bit 13: signal 6 set */ -#define SP_STATUS_SIG7 0x4000 /* Bit 14: signal 7 set */ +#define SP_STATUS_HALT (1 << 0) +#define SP_STATUS_BROKE (1 << 1) +#define SP_STATUS_DMA_BUSY (1 << 2) +#define SP_STATUS_DMA_FULL (1 << 3) +#define SP_STATUS_IO_FULL (1 << 4) +#define SP_STATUS_SSTEP (1 << 5) +#define SP_STATUS_INTR_BREAK (1 << 6) +#define SP_STATUS_SIG0 (1 << 7) +#define SP_STATUS_SIG1 (1 << 8) +#define SP_STATUS_SIG2 (1 << 9) +#define SP_STATUS_SIG3 (1 << 10) +#define SP_STATUS_SIG4 (1 << 11) +#define SP_STATUS_SIG5 (1 << 12) +#define SP_STATUS_SIG6 (1 << 13) +#define SP_STATUS_SIG7 (1 << 14) /* - * Use of SIG bits + * SP_STATUS_REG: use of SIG bits */ -#define SP_CLR_YIELD SP_CLR_SIG0 -#define SP_SET_YIELD SP_SET_SIG0 -#define SP_STATUS_YIELD SP_STATUS_SIG0 -#define SP_CLR_YIELDED SP_CLR_SIG1 -#define SP_SET_YIELDED SP_SET_SIG1 -#define SP_STATUS_YIELDED SP_STATUS_SIG1 -#define SP_CLR_TASKDONE SP_CLR_SIG2 -#define SP_SET_TASKDONE SP_SET_SIG2 -#define SP_STATUS_TASKDONE SP_STATUS_SIG2 -#define SP_CLR_RSPSIGNAL SP_CLR_SIG3 -#define SP_SET_RSPSIGNAL SP_SET_SIG3 -#define SP_STATUS_RSPSIGNAL SP_STATUS_SIG3 -#define SP_CLR_CPUSIGNAL SP_CLR_SIG4 -#define SP_SET_CPUSIGNAL SP_SET_SIG4 -#define SP_STATUS_CPUSIGNAL SP_STATUS_SIG4 - -/* SP IMEM BIST REG (R/W): [6:0] BIST status bits; see below for detail */ -#define SP_IBIST_REG 0x04080004 +#define SP_CLR_YIELD SP_CLR_SIG0 +#define SP_SET_YIELD SP_SET_SIG0 +#define SP_STATUS_YIELD SP_STATUS_SIG0 +#define SP_CLR_YIELDED SP_CLR_SIG1 +#define SP_SET_YIELDED SP_SET_SIG1 +#define SP_STATUS_YIELDED SP_STATUS_SIG1 +#define SP_CLR_TASKDONE SP_CLR_SIG2 +#define SP_SET_TASKDONE SP_SET_SIG2 +#define SP_STATUS_TASKDONE SP_STATUS_SIG2 +#define SP_CLR_RSPSIGNAL SP_CLR_SIG3 +#define SP_SET_RSPSIGNAL SP_SET_SIG3 +#define SP_STATUS_RSPSIGNAL SP_STATUS_SIG3 +#define SP_CLR_CPUSIGNAL SP_CLR_SIG4 +#define SP_SET_CPUSIGNAL SP_SET_SIG4 +#define SP_STATUS_CPUSIGNAL SP_STATUS_SIG4 /* - * Patterns to interpret status reg (SP_BIST_REG - write) + * SP IMEM BIST REG (R/W): [6:0] BIST status bits; see below for detail */ -#define SP_IBIST_CHECK 0x01 /* Bit 0: BIST check */ -#define SP_IBIST_GO 0x02 /* Bit 1: BIST go */ -#define SP_IBIST_CLEAR 0x04 /* Bit 2: BIST clear */ +#define SP_IBIST_REG 0x04080004 /* - * Patterns to interpret status reg (SP_BIST_REG - read) + * SP_IBIST_REG: write bits */ -/* First 2 bits are same as in write mode: - * Bit 0: BIST check; Bit 1: BIST go - */ -#define SP_IBIST_DONE 0x04 /* Bit 2: BIST done */ -#define SP_IBIST_FAILED 0x78 /* Bit [6:3]: BIST fail */ +#define SP_IBIST_CHECK (1 << 0) /* BIST check */ +#define SP_IBIST_GO (1 << 1) /* BIST go */ +#define SP_IBIST_CLEAR (1 << 2) /* BIST clear */ - -/************************************************************************* - * DP Command Registers +/* + * SP_BIST_REG: read bits + * First 2 bits are same as in write mode */ -#define DPC_BASE_REG 0x04100000 +#define SP_IBIST_DONE (1 << 2) +#define SP_IBIST_FAILED 0x78 /* bits [6:3], BIST fail */ + +/** + * Display Processor Command (DPC) Registers + */ +#define DPC_BASE_REG 0x04100000 /* DP CMD DMA start (R/W): [23:0] DMEM/RDRAM start address */ -#define DPC_START_REG (DPC_BASE_REG+0x00) +#define DPC_START_REG (DPC_BASE_REG + 0x00) /* DP CMD DMA end (R/W): [23:0] DMEM/RDRAM end address */ -#define DPC_END_REG (DPC_BASE_REG+0x04) +#define DPC_END_REG (DPC_BASE_REG + 0x04) /* DP CMD DMA end (R): [23:0] DMEM/RDRAM current address */ -#define DPC_CURRENT_REG (DPC_BASE_REG+0x08) +#define DPC_CURRENT_REG (DPC_BASE_REG + 0x08) /* DP CMD status (R/W): [9:0] valid bits - see below for definitions */ -#define DPC_STATUS_REG (DPC_BASE_REG+0x0C) +#define DPC_STATUS_REG (DPC_BASE_REG + 0x0C) /* DP clock counter (R): [23:0] clock counter */ -#define DPC_CLOCK_REG (DPC_BASE_REG+0x10) +#define DPC_CLOCK_REG (DPC_BASE_REG + 0x10) /* DP buffer busy counter (R): [23:0] clock counter */ -#define DPC_BUFBUSY_REG (DPC_BASE_REG+0x14) +#define DPC_BUFBUSY_REG (DPC_BASE_REG + 0x14) /* DP pipe busy counter (R): [23:0] clock counter */ -#define DPC_PIPEBUSY_REG (DPC_BASE_REG+0x18) +#define DPC_PIPEBUSY_REG (DPC_BASE_REG + 0x18) /* DP TMEM load counter (R): [23:0] clock counter */ -#define DPC_TMEM_REG (DPC_BASE_REG+0x1C) +#define DPC_TMEM_REG (DPC_BASE_REG + 0x1C) -/* - * Values to clear/set bit in status reg (DPC_STATUS_REG - write) +/** + * DPC_STATUS_REG: write bits */ -#define DPC_CLR_XBUS_DMEM_DMA 0x0001 /* Bit 0: clear xbus_dmem_dma */ -#define DPC_SET_XBUS_DMEM_DMA 0x0002 /* Bit 1: set xbus_dmem_dma */ -#define DPC_CLR_FREEZE 0x0004 /* Bit 2: clear freeze */ -#define DPC_SET_FREEZE 0x0008 /* Bit 3: set freeze */ -#define DPC_CLR_FLUSH 0x0010 /* Bit 4: clear flush */ -#define DPC_SET_FLUSH 0x0020 /* Bit 5: set flush */ -#define DPC_CLR_TMEM_CTR 0x0040 /* Bit 6: clear tmem ctr */ -#define DPC_CLR_PIPE_CTR 0x0080 /* Bit 7: clear pipe ctr */ -#define DPC_CLR_CMD_CTR 0x0100 /* Bit 8: clear cmd ctr */ -#define DPC_CLR_CLOCK_CTR 0x0200 /* Bit 9: clear clock ctr */ +#define DPC_CLR_XBUS_DMEM_DMA (1 << 0) +#define DPC_SET_XBUS_DMEM_DMA (1 << 1) +#define DPC_CLR_FREEZE (1 << 2) +#define DPC_SET_FREEZE (1 << 3) +#define DPC_CLR_FLUSH (1 << 4) +#define DPC_SET_FLUSH (1 << 5) +#define DPC_CLR_TMEM_CTR (1 << 6) +#define DPC_CLR_PIPE_CTR (1 << 7) +#define DPC_CLR_CMD_CTR (1 << 8) +#define DPC_CLR_CLOCK_CTR (1 << 9) -/* - * Patterns to interpret status reg (DPC_STATUS_REG - read) +/** + * DPC_STATUS_REG: read bits */ -#define DPC_STATUS_XBUS_DMEM_DMA 0x001 /* Bit 0: xbus_dmem_dma */ -#define DPC_STATUS_FREEZE 0x002 /* Bit 1: freeze */ -#define DPC_STATUS_FLUSH 0x004 /* Bit 2: flush */ -/*#define DPC_STATUS_FROZEN 0x008*/ /* Bit 3: frozen */ -#define DPC_STATUS_START_GCLK 0x008 /* Bit 3: start gclk */ -#define DPC_STATUS_TMEM_BUSY 0x010 /* Bit 4: tmem busy */ -#define DPC_STATUS_PIPE_BUSY 0x020 /* Bit 5: pipe busy */ -#define DPC_STATUS_CMD_BUSY 0x040 /* Bit 6: cmd busy */ -#define DPC_STATUS_CBUF_READY 0x080 /* Bit 7: cbuf ready */ -#define DPC_STATUS_DMA_BUSY 0x100 /* Bit 8: dma busy */ -#define DPC_STATUS_END_VALID 0x200 /* Bit 9: end valid */ -#define DPC_STATUS_START_VALID 0x400 /* Bit 10: start valid */ +#define DPC_STATUS_XBUS_DMEM_DMA (1 << 0) +#define DPC_STATUS_FREEZE (1 << 1) +#define DPC_STATUS_FLUSH (1 << 2) +#define DPC_STATUS_START_GCLK (1 << 3) +#define DPC_STATUS_TMEM_BUSY (1 << 4) +#define DPC_STATUS_PIPE_BUSY (1 << 5) +#define DPC_STATUS_CMD_BUSY (1 << 6) +#define DPC_STATUS_CBUF_READY (1 << 7) +#define DPC_STATUS_DMA_BUSY (1 << 8) +#define DPC_STATUS_END_VALID (1 << 9) +#define DPC_STATUS_START_VALID (1 << 10) - -/************************************************************************* - * DP Span Registers +/** + * Display Processor Span (DPS) Registers */ -#define DPS_BASE_REG 0x04200000 +#define DPS_BASE_REG 0x04200000 -/* DP tmem bist (R/W): [10:0] BIST status bits; see below for detail */ -#define DPS_TBIST_REG (DPS_BASE_REG+0x00) +/* DP tmem built-in self-test (R/W): [10:0] BIST status bits */ +#define DPS_TBIST_REG (DPS_BASE_REG + 0x00) /* DP span test mode (R/W): [0] Span buffer test access enable */ -#define DPS_TEST_MODE_REG (DPS_BASE_REG+0x04) +#define DPS_TEST_MODE_REG (DPS_BASE_REG + 0x04) -/* DP span buffer test address (R/W): [6:0] bits; see below for detail */ -#define DPS_BUFTEST_ADDR_REG (DPS_BASE_REG+0x08) +/* DP span buffer test address (R/W): [6:0] bits */ +#define DPS_BUFTEST_ADDR_REG (DPS_BASE_REG + 0x08) /* DP span buffer test data (R/W): [31:0] span buffer data */ -#define DPS_BUFTEST_DATA_REG (DPS_BASE_REG+0x0C) +#define DPS_BUFTEST_DATA_REG (DPS_BASE_REG + 0x0C) /* - * Patterns to interpret status reg (DPS_TMEM_BIST_REG - write) + * DPS_TMEM_BIST_REG: write bits */ -#define DPS_TBIST_CHECK 0x01 /* Bit 0: BIST check */ -#define DPS_TBIST_GO 0x02 /* Bit 1: BIST go */ -#define DPS_TBIST_CLEAR 0x04 /* Bit 2: BIST clear */ +#define DPS_TBIST_CHECK (1 << 0) +#define DPS_TBIST_GO (1 << 1) +#define DPS_TBIST_CLEAR (1 << 2) /* - * Patterns to interpret status reg (DPS_TMEM_BIST_REG - read) + * DPS_TMEM_BIST_REG: read bits + * First 2 bits are same as in write mode */ -/* First 2 bits are same as in write mode: - * Bit 0: BIST check; Bit 1: BIST go - */ -#define DPS_TBIST_DONE 0x004 /* Bit 2: BIST done */ -#define DPS_TBIST_FAILED 0x7F8 /* Bit [10:3]: BIST fail */ +#define DPS_TBIST_DONE (1 << 2) +#define DPS_TBIST_FAILED 0x7F8 /* bits [10:3], BIST fail */ - -/************************************************************************* - * MIPS Interface (MI) Registers +/** + * MIPS Interface (MI) Registers */ -#define MI_BASE_REG 0x04300000 +#define MI_BASE_REG 0x04300000 /* * MI init mode (W): [6:0] init length, [7] clear init mode, [8] set init mode * [9/10] clear/set ebus test mode, [11] clear DP interrupt * (R): [6:0] init length, [7] init mode, [8] ebus test mode */ -#define MI_INIT_MODE_REG (MI_BASE_REG+0x00) -#define MI_MODE_REG MI_INIT_MODE_REG +#define MI_INIT_MODE_REG (MI_BASE_REG + 0x00) +#define MI_MODE_REG MI_INIT_MODE_REG /* - * Values to clear/set bit in mode reg (MI_MODE_REG - write) + * MI_MODE_REG: write bits */ -#define MI_CLR_INIT 0x0080 /* Bit 7: clear init mode */ -#define MI_SET_INIT 0x0100 /* Bit 8: set init mode */ -#define MI_CLR_EBUS 0x0200 /* Bit 9: clear ebus test */ -#define MI_SET_EBUS 0x0400 /* Bit 10: set ebus test mode */ -#define MI_CLR_DP_INTR 0x0800 /* Bit 11: clear dp interrupt */ -#define MI_CLR_RDRAM 0x1000 /* Bit 12: clear RDRAM reg */ -#define MI_SET_RDRAM 0x2000 /* Bit 13: set RDRAM reg mode */ +#define MI_CLR_INIT (1 << 7) /* clear init mode */ +#define MI_SET_INIT (1 << 8) /* set init mode */ +#define MI_CLR_EBUS (1 << 9) /* clear ebus test */ +#define MI_SET_EBUS (1 << 10) /* set ebus test mode */ +#define MI_CLR_DP_INTR (1 << 11) /* clear dp interrupt */ +#define MI_CLR_RDRAM (1 << 12) /* clear RDRAM reg */ +#define MI_SET_RDRAM (1 << 13) /* set RDRAM reg mode */ /* - * Patterns to interpret mode reg (MI_MODE_REG - read) + * MI_MODE_REG: read bits */ -#define MI_MODE_INIT 0x0080 /* Bit 7: init mode */ -#define MI_MODE_EBUS 0x0100 /* Bit 8: ebus test mode */ -#define MI_MODE_RDRAM 0x0200 /* Bit 9: RDRAM reg mode */ +#define MI_MODE_INIT (1 << 7) /* init mode */ +#define MI_MODE_EBUS (1 << 8) /* ebus test mode */ +#define MI_MODE_RDRAM (1 << 9) /* RDRAM reg mode */ /* MI version (R): [7:0] io, [15:8] rac, [23:16] rdp, [31:24] rsp */ -#define MI_VERSION_REG (MI_BASE_REG+0x04) -#define MI_NOOP_REG MI_VERSION_REG +#define MI_VERSION_REG (MI_BASE_REG + 0x04) +#define MI_NOOP_REG MI_VERSION_REG /* MI interrupt (R): [5:0] valid bits - see below for bit patterns */ -#define MI_INTR_REG (MI_BASE_REG+0x08) +#define MI_INTR_REG (MI_BASE_REG + 0x08) /* * MI interrupt mask (W): [11:0] valid bits - see below for bit patterns * (R): [5:0] valid bits - see below for bit patterns */ -#define MI_INTR_MASK_REG (MI_BASE_REG+0x0C) +#define MI_INTR_MASK_REG (MI_BASE_REG + 0x0C) /* - * The following are values to check for interrupt setting (MI_INTR_REG) + * MI_INTR_REG: read bits */ -#define MI_INTR_SP 0x01 /* Bit 0: SP intr */ -#define MI_INTR_SI 0x02 /* Bit 1: SI intr */ -#define MI_INTR_AI 0x04 /* Bit 2: AI intr */ -#define MI_INTR_VI 0x08 /* Bit 3: VI intr */ -#define MI_INTR_PI 0x10 /* Bit 4: PI intr */ -#define MI_INTR_DP 0x20 /* Bit 5: DP intr */ +#define MI_INTR_SP (1 << 0) /* SP intr */ +#define MI_INTR_SI (1 << 1) /* SI intr */ +#define MI_INTR_AI (1 << 2) /* AI intr */ +#define MI_INTR_VI (1 << 3) /* VI intr */ +#define MI_INTR_PI (1 << 4) /* PI intr */ +#define MI_INTR_DP (1 << 5) /* DP intr */ /* - * The following are values to clear/set various interrupt bit mask - * They can be ORed together to manipulate multiple bits - * (MI_INTR_MASK_REG - write) + * MI_INTR_MASK_REG: write bits */ -#define MI_INTR_MASK_CLR_SP 0x0001 /* Bit 0: clear SP mask */ -#define MI_INTR_MASK_SET_SP 0x0002 /* Bit 1: set SP mask */ -#define MI_INTR_MASK_CLR_SI 0x0004 /* Bit 2: clear SI mask */ -#define MI_INTR_MASK_SET_SI 0x0008 /* Bit 3: set SI mask */ -#define MI_INTR_MASK_CLR_AI 0x0010 /* Bit 4: clear AI mask */ -#define MI_INTR_MASK_SET_AI 0x0020 /* Bit 5: set AI mask */ -#define MI_INTR_MASK_CLR_VI 0x0040 /* Bit 6: clear VI mask */ -#define MI_INTR_MASK_SET_VI 0x0080 /* Bit 7: set VI mask */ -#define MI_INTR_MASK_CLR_PI 0x0100 /* Bit 8: clear PI mask */ -#define MI_INTR_MASK_SET_PI 0x0200 /* Bit 9: set PI mask */ -#define MI_INTR_MASK_CLR_DP 0x0400 /* Bit 10: clear DP mask */ -#define MI_INTR_MASK_SET_DP 0x0800 /* Bit 11: set DP mask */ +#define MI_INTR_MASK_CLR_SP (1 << 0) /* clear SP mask */ +#define MI_INTR_MASK_SET_SP (1 << 1) /* set SP mask */ +#define MI_INTR_MASK_CLR_SI (1 << 2) /* clear SI mask */ +#define MI_INTR_MASK_SET_SI (1 << 3) /* set SI mask */ +#define MI_INTR_MASK_CLR_AI (1 << 4) /* clear AI mask */ +#define MI_INTR_MASK_SET_AI (1 << 5) /* set AI mask */ +#define MI_INTR_MASK_CLR_VI (1 << 6) /* clear VI mask */ +#define MI_INTR_MASK_SET_VI (1 << 7) /* set VI mask */ +#define MI_INTR_MASK_CLR_PI (1 << 8) /* clear PI mask */ +#define MI_INTR_MASK_SET_PI (1 << 9) /* set PI mask */ +#define MI_INTR_MASK_CLR_DP (1 << 10) /* clear DP mask */ +#define MI_INTR_MASK_SET_DP (1 << 11) /* set DP mask */ /* - * The following are values to check for interrupt mask setting - * (MI_INTR_MASK_REG - read) + * MI_INTR_MASK_REG: read bits */ -#define MI_INTR_MASK_SP 0x01 /* Bit 0: SP intr mask */ -#define MI_INTR_MASK_SI 0x02 /* Bit 1: SI intr mask */ -#define MI_INTR_MASK_AI 0x04 /* Bit 2: AI intr mask */ -#define MI_INTR_MASK_VI 0x08 /* Bit 3: VI intr mask */ -#define MI_INTR_MASK_PI 0x10 /* Bit 4: PI intr mask */ -#define MI_INTR_MASK_DP 0x20 /* Bit 5: DP intr mask */ +#define MI_INTR_MASK_SP (1 << 0) /* SP intr mask */ +#define MI_INTR_MASK_SI (1 << 1) /* SI intr mask */ +#define MI_INTR_MASK_AI (1 << 2) /* AI intr mask */ +#define MI_INTR_MASK_VI (1 << 3) /* VI intr mask */ +#define MI_INTR_MASK_PI (1 << 4) /* PI intr mask */ +#define MI_INTR_MASK_DP (1 << 5) /* DP intr mask */ - -/************************************************************************* - * Video Interface (VI) Registers +/** + * Video Interface (VI) Registers */ -#define VI_BASE_REG 0x04400000 +#define VI_BASE_REG 0x04400000 /* VI status/control (R/W): [15-0] valid bits: - * [1:0] = type[1:0] (pixel size) - * 0: blank (no data, no sync) + * [1:0] = type[1:0] (pixel size) + * 0: blank (no data, no sync) * 1: reserved * 2: 5/5/5/3 ("16" bit) * 3: 8/8/8/8 (32 bit) - * [2] = gamma_dither_enable (normally on, unless "special effect") - * [3] = gamma_enable (normally on, unless MPEG/JPEG) - * [4] = divot_enable (normally on if antialiased, unless decal lines) - * [5] = reserved - always off - * [6] = serrate (always on if interlaced, off if not) - * [7] = reserved - diagnostics only - * [9:8] = anti-alias (aa) mode[1:0] - * 0: aa & resamp (always fetch extra lines) + * [2] = gamma_dither_enable (normally on, unless "special effect") + * [3] = gamma_enable (normally on, unless MPEG/JPEG) + * [4] = divot_enable (normally on if antialiased, unless decal lines) + * [5] = reserved - always off + * [6] = serrate (always on if interlaced, off if not) + * [7] = reserved - diagnostics only + * [9:8] = anti-alias (aa) mode[1:0] + * 0: aa & resamp (always fetch extra lines) * 1: aa & resamp (fetch extra lines if needed) * 2: resamp only (treat as all fully covered) * 3: neither (replicate pixels, no interpolate) - * [11] = reserved - diagnostics only - * [15:12] = reserved + * [11] = reserved - diagnostics only + * [15:12] = reserved * */ -#define VI_STATUS_REG (VI_BASE_REG+0x00) -#define VI_CONTROL_REG VI_STATUS_REG +#define VI_CONTROL_REG (VI_BASE_REG + 0x00) +#define VI_STATUS_REG VI_CONTROL_REG /* VI origin (R/W): [23:0] frame buffer origin in bytes */ -#define VI_ORIGIN_REG (VI_BASE_REG+0x04) -#define VI_DRAM_ADDR_REG VI_ORIGIN_REG +#define VI_ORIGIN_REG (VI_BASE_REG + 0x04) +#define VI_DRAM_ADDR_REG VI_ORIGIN_REG /* VI width (R/W): [11:0] frame buffer line width in pixels */ -#define VI_WIDTH_REG (VI_BASE_REG+0x08) -#define VI_H_WIDTH_REG VI_WIDTH_REG +#define VI_WIDTH_REG (VI_BASE_REG + 0x08) +#define VI_H_WIDTH_REG VI_WIDTH_REG /* VI vertical intr (R/W): [9:0] interrupt when current half-line = V_INTR */ -#define VI_INTR_REG (VI_BASE_REG+0x0C) -#define VI_V_INTR_REG VI_INTR_REG +#define VI_INTR_REG (VI_BASE_REG + 0x0C) +#define VI_V_INTR_REG VI_INTR_REG /* * VI current vertical line (R/W): [9:0] current half line, sampled once per - * line (the lsb of V_CURRENT is constant within a field, and in - * interlaced modes gives the field number - which is constant for non- - * interlaced modes) - * - Any write to this register will clear interrupt line + * line (the lsb of V_CURRENT is constant within a field, and in + * interlaced modes gives the field number - which is constant for non- + * interlaced modes) + * - Any write to this register will clear interrupt line */ -#define VI_CURRENT_REG (VI_BASE_REG+0x10) -#define VI_V_CURRENT_LINE_REG VI_CURRENT_REG +#define VI_CURRENT_REG (VI_BASE_REG + 0x10) +#define VI_V_CURRENT_LINE_REG VI_CURRENT_REG /* * VI video timing (R/W): [ 7: 0] horizontal sync width in pixels, - * [15: 8] color burst width in pixels, + * [15: 8] color burst width in pixels, * [19:16] vertical sync width in half lines, - * [29:20] start of color burst in pixels from h-sync + * [29:20] start of color burst in pixels from h-sync */ -#define VI_BURST_REG (VI_BASE_REG+0x14) -#define VI_TIMING_REG VI_BURST_REG +#define VI_BURST_REG (VI_BASE_REG + 0x14) +#define VI_TIMING_REG VI_BURST_REG /* VI vertical sync (R/W): [9:0] number of half-lines per field */ -#define VI_V_SYNC_REG (VI_BASE_REG+0x18) +#define VI_V_SYNC_REG (VI_BASE_REG + 0x18) /* VI horizontal sync (R/W): [11: 0] total duration of a line in 1/4 pixel - * [20:16] a 5-bit leap pattern used for PAL only - * (h_sync_period) + * [20:16] a 5-bit leap pattern used for PAL only + * (h_sync_period) */ -#define VI_H_SYNC_REG (VI_BASE_REG+0x1C) +#define VI_H_SYNC_REG (VI_BASE_REG + 0x1C) /* * VI horizontal sync leap (R/W): [11: 0] identical to h_sync_period * [27:16] identical to h_sync_period */ -#define VI_LEAP_REG (VI_BASE_REG+0x20) -#define VI_H_SYNC_LEAP_REG VI_LEAP_REG +#define VI_LEAP_REG (VI_BASE_REG + 0x20) +#define VI_H_SYNC_LEAP_REG VI_LEAP_REG /* * VI horizontal video (R/W): [ 9: 0] end of active video in screen pixels * : [25:16] start of active video in screen pixels */ -#define VI_H_START_REG (VI_BASE_REG+0x24) -#define VI_H_VIDEO_REG VI_H_START_REG +#define VI_H_START_REG (VI_BASE_REG + 0x24) +#define VI_H_VIDEO_REG VI_H_START_REG /* * VI vertical video (R/W): [ 9: 0] end of active video in screen half-lines * : [25:16] start of active video in screen half-lines */ -#define VI_V_START_REG (VI_BASE_REG+0x28) -#define VI_V_VIDEO_REG VI_V_START_REG +#define VI_V_START_REG (VI_BASE_REG + 0x28) +#define VI_V_VIDEO_REG VI_V_START_REG /* * VI vertical burst (R/W): [ 9: 0] end of color burst enable in half-lines * : [25:16] start of color burst enable in half-lines */ -#define VI_V_BURST_REG (VI_BASE_REG+0x2C) +#define VI_V_BURST_REG (VI_BASE_REG + 0x2C) /* VI x-scale (R/W): [11: 0] 1/horizontal scale up factor (2.10 format) - * [27:16] horizontal subpixel offset (2.10 format) + * [27:16] horizontal subpixel offset (2.10 format) */ -#define VI_X_SCALE_REG (VI_BASE_REG+0x30) +#define VI_X_SCALE_REG (VI_BASE_REG + 0x30) /* VI y-scale (R/W): [11: 0] 1/vertical scale up factor (2.10 format) - * [27:16] vertical subpixel offset (2.10 format) + * [27:16] vertical subpixel offset (2.10 format) */ -#define VI_Y_SCALE_REG (VI_BASE_REG+0x34) +#define VI_Y_SCALE_REG (VI_BASE_REG + 0x34) /* * Patterns to interpret VI_CONTROL_REG */ -#define VI_CTRL_TYPE_16 0x00002 /* Bit [1:0] pixel size: 16 bit */ -#define VI_CTRL_TYPE_32 0x00003 /* Bit [1:0] pixel size: 32 bit */ -#define VI_CTRL_GAMMA_DITHER_ON 0x00004 /* Bit 2: default = on */ -#define VI_CTRL_GAMMA_ON 0x00008 /* Bit 3: default = on */ -#define VI_CTRL_DIVOT_ON 0x00010 /* Bit 4: default = on */ -#define VI_CTRL_SERRATE_ON 0x00040 /* Bit 6: on if interlaced */ -#define VI_CTRL_ANTIALIAS_MASK 0x00300 /* Bit [9:8] anti-alias mode */ -#define VI_CTRL_DITHER_FILTER_ON 0x10000 /* Bit 16: dither-filter mode */ +#define VI_CTRL_TYPE_16 0x00002 /* [1:0] pixel size: 16 bit */ +#define VI_CTRL_TYPE_32 0x00003 /* [1:0] pixel size: 32 bit */ +#define VI_CTRL_GAMMA_DITHER_ON 0x00004 /* 2: default = on */ +#define VI_CTRL_GAMMA_ON 0x00008 /* 3: default = on */ +#define VI_CTRL_DIVOT_ON 0x00010 /* 4: default = on */ +#define VI_CTRL_SERRATE_ON 0x00040 /* 6: on if interlaced */ +#define VI_CTRL_ANTIALIAS_MASK 0x00300 /* [9:8] anti-alias mode */ +#define VI_CTRL_ANTIALIAS_MODE_1 0x00100 /* Bit [9:8] anti-alias mode */ +#define VI_CTRL_ANTIALIAS_MODE_2 0x00200 /* Bit [9:8] anti-alias mode */ +#define VI_CTRL_ANTIALIAS_MODE_3 0x00300 /* Bit [9:8] anti-alias mode */ +#define VI_CTRL_PIXEL_ADV_MASK 0x01000 /* [15:12] pixel advance mode? */ +#define VI_CTRL_PIXEL_ADV_1 0x01000 /* Bit [15:12] pixel advance mode? */ +#define VI_CTRL_PIXEL_ADV_2 0x02000 /* Bit [15:12] pixel advance mode? */ +#ifndef BBPLAYER +#define VI_CTRL_PIXEL_ADV_3 0x03000 /* Bit [15:12] pixel advance mode? */ +#else +#define VI_CTRL_PIXEL_ADV_3 0x01000 /* Bit [15:12] pixel advance mode? */ +#endif +#define VI_CTRL_DITHER_FILTER_ON 0x10000 /* 16: dither-filter mode */ /* * Possible video clocks (NTSC or PAL) */ -#define VI_NTSC_CLOCK 48681812 /* Hz = 48.681812 MHz */ -#define VI_PAL_CLOCK 49656530 /* Hz = 49.656530 MHz */ -#define VI_MPAL_CLOCK 48628316 /* Hz = 48.628316 MHz */ +#define VI_NTSC_CLOCK 48681812 /* Hz = 48.681812 MHz */ +#define VI_PAL_CLOCK 49656530 /* Hz = 49.656530 MHz */ +#define VI_MPAL_CLOCK 48628316 /* Hz = 48.628316 MHz */ - -/************************************************************************* - * Audio Interface (AI) Registers - * +/** * The address and length registers are double buffered; that is, they * can be written twice before becoming full. * The address must be written before the length. */ -#define AI_BASE_REG 0x04500000 + +/** + * Audio Interface (AI) Registers + */ +#define AI_BASE_REG 0x04500000 /* AI DRAM address (W): [23:0] starting RDRAM address (8B-aligned) */ -#define AI_DRAM_ADDR_REG (AI_BASE_REG+0x00) /* R0: DRAM address */ +#define AI_DRAM_ADDR_REG (AI_BASE_REG + 0x00) /* R0: DRAM address */ /* AI length (R/W): [14:0] transfer length (v1.0) - Bottom 3 bits are ignored */ /* [17:0] transfer length (v2.0) - Bottom 3 bits are ignored */ -#define AI_LEN_REG (AI_BASE_REG+0x04) /* R1: Length */ +#define AI_LEN_REG (AI_BASE_REG + 0x04) /* R1: Length */ /* AI control (W): [0] DMA enable - if LSB == 1, DMA is enabled */ -#define AI_CONTROL_REG (AI_BASE_REG+0x08) /* R2: DMA Control */ +#define AI_CONTROL_REG (AI_BASE_REG + 0x08) /* R2: DMA Control */ + +/* Value for control register */ +#define AI_CONTROL_DMA_ON 1 /* LSB = 1: DMA enable*/ +#define AI_CONTROL_DMA_OFF 0 /* LSB = 1: DMA enable*/ /* * AI status (R): [31]/[0] ai_full (addr & len buffer full), [30] ai_busy - * Note that a 1->0 transition in ai_full will set interrupt + * Note that a 1->0 transition in ai_full will set interrupt * (W): clear audio interrupt */ -#define AI_STATUS_REG (AI_BASE_REG+0x0C) /* R3: Status */ +#define AI_STATUS_REG (AI_BASE_REG + 0x0C) /* R3: Status */ + +/* Value for status register */ +#define AI_STATUS_FIFO_FULL (1 << 31) +#define AI_STATUS_DMA_BUSY (1 << 30) /* * AI DAC sample period register (W): [13:0] dac rate * - vid_clock/(dperiod + 1) is the DAC sample rate * - (dperiod + 1) >= 66 * (aclockhp + 1) must be true */ -#define AI_DACRATE_REG (AI_BASE_REG+0x10) /* R4: DAC rate 14-lsb*/ +#define AI_DACRATE_REG (AI_BASE_REG + 0x10) /* R4: DAC rate 14-lsb*/ + +/* DAC rate = video clock / audio frequency + * - DAC rate >= (66 * Bit rate) must be true + */ +#define AI_MAX_DAC_RATE 16384 /* 14-bit+1 */ +#define AI_MIN_DAC_RATE 132 /* * AI bit rate (W): [3:0] bit rate (abus clock half period register - aclockhp) * - vid_clock/(2 * (aclockhp + 1)) is the DAC clock rate * - The abus clock stops if aclockhp is zero */ -#define AI_BITRATE_REG (AI_BASE_REG+0x14) /* R5: Bit rate 4-lsb */ - -/* Value for control register */ -#define AI_CONTROL_DMA_ON 0x01 /* LSB = 1: DMA enable*/ -#define AI_CONTROL_DMA_OFF 0x00 /* LSB = 1: DMA enable*/ - -/* Value for status register */ -#define AI_STATUS_FIFO_FULL 0x80000000 /* Bit 31: full */ -#define AI_STATUS_DMA_BUSY 0x40000000 /* Bit 30: busy */ - -/* DAC rate = video clock / audio frequency - * - DAC rate >= (66 * Bit rate) must be true - */ -#define AI_MAX_DAC_RATE 16384 /* 14-bit+1 */ -#define AI_MIN_DAC_RATE 132 +#define AI_BITRATE_REG (AI_BASE_REG + 0x14) /* R5: Bit rate 4-lsb */ /* Bit rate <= (DAC rate / 66) */ -#define AI_MAX_BIT_RATE 16 /* 4-bit+1 */ -#define AI_MIN_BIT_RATE 2 +#define AI_MAX_BIT_RATE 16 /* 4-bit+1 */ +#define AI_MIN_BIT_RATE 2 /* * Maximum and minimum values for audio frequency based on video clocks * max frequency = (video clock / min dac rate) * min frequency = (video clock / max dac rate) */ -#define AI_NTSC_MAX_FREQ 368000 /* 368 KHz */ -#define AI_NTSC_MIN_FREQ 3000 /* 3 KHz ~ 2971 Hz */ +#define AI_NTSC_MAX_FREQ 368000 /* 368 KHz */ +#define AI_NTSC_MIN_FREQ 3000 /* 3 KHz ~ 2971 Hz */ -#define AI_PAL_MAX_FREQ 376000 /* 376 KHz */ -#define AI_PAL_MIN_FREQ 3050 /* 3 KHz ~ 3031 Hz */ +#define AI_PAL_MAX_FREQ 376000 /* 376 KHz */ +#define AI_PAL_MIN_FREQ 3050 /* 3 KHz ~ 3031 Hz */ -#define AI_MPAL_MAX_FREQ 368000 /* 368 KHz */ -#define AI_MPAL_MIN_FREQ 3000 /* 3 KHz ~ 2968 Hz */ +#define AI_MPAL_MAX_FREQ 368000 /* 368 KHz */ +#define AI_MPAL_MIN_FREQ 3000 /* 3 KHz ~ 2968 Hz */ - -/************************************************************************* +/** * Peripheral Interface (PI) Registers */ -#define PI_BASE_REG 0x04600000 +#define PI_BASE_REG 0x04600000 /* PI DRAM address (R/W): [23:0] starting RDRAM address */ -#define PI_DRAM_ADDR_REG (PI_BASE_REG+0x00) /* DRAM address */ +#define PI_DRAM_ADDR_REG (PI_BASE_REG + 0x00) /* DRAM address */ /* PI pbus (cartridge) address (R/W): [31:0] starting AD16 address */ -#define PI_CART_ADDR_REG (PI_BASE_REG+0x04) +#define PI_CART_ADDR_REG (PI_BASE_REG + 0x04) /* PI read length (R/W): [23:0] read data length */ -#define PI_RD_LEN_REG (PI_BASE_REG+0x08) +#define PI_RD_LEN_REG (PI_BASE_REG + 0x08) /* PI write length (R/W): [23:0] write data length */ -#define PI_WR_LEN_REG (PI_BASE_REG+0x0C) +#define PI_WR_LEN_REG (PI_BASE_REG + 0x0C) /* * PI status (R): [0] DMA busy, [1] IO busy, [2], error * (W): [0] reset controller (and abort current op), [1] clear intr */ -#define PI_STATUS_REG (PI_BASE_REG+0x10) +#define PI_STATUS_REG (PI_BASE_REG + 0x10) /* PI dom1 latency (R/W): [7:0] domain 1 device latency */ -#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG+0x14) +#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG + 0x14) /* PI dom1 pulse width (R/W): [7:0] domain 1 device R/W strobe pulse width */ -#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG+0x18) +#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG + 0x18) /* PI dom1 page size (R/W): [3:0] domain 1 device page size */ -#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG+0x1C) /* page size */ +#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG + 0x1C) /* page size */ /* PI dom1 release (R/W): [1:0] domain 1 device R/W release duration */ -#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG+0x20) +#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG + 0x20) /* PI dom2 latency (R/W): [7:0] domain 2 device latency */ -#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG+0x24) /* Domain 2 latency */ +#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG + 0x24) /* Domain 2 latency */ /* PI dom2 pulse width (R/W): [7:0] domain 2 device R/W strobe pulse width */ -#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG+0x28) /* pulse width */ +#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG + 0x28) /* pulse width */ /* PI dom2 page size (R/W): [3:0] domain 2 device page size */ -#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG+0x2C) /* page size */ +#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG + 0x2C) /* page size */ /* PI dom2 release (R/W): [1:0] domain 2 device R/W release duration */ -#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG+0x30) /* release duration */ +#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG + 0x30) /* release duration */ -#define PI_DOMAIN1_REG PI_BSD_DOM1_LAT_REG -#define PI_DOMAIN2_REG PI_BSD_DOM2_LAT_REG +#define PI_DOMAIN1_REG PI_BSD_DOM1_LAT_REG +#define PI_DOMAIN2_REG PI_BSD_DOM2_LAT_REG -#define PI_DOM_LAT_OFS 0x00 -#define PI_DOM_PWD_OFS 0x04 -#define PI_DOM_PGS_OFS 0x08 -#define PI_DOM_RLS_OFS 0x0C +#define PI_DOM_LAT_OFS 0x00 +#define PI_DOM_PWD_OFS 0x04 +#define PI_DOM_PGS_OFS 0x08 +#define PI_DOM_RLS_OFS 0x0C /* * PI status register has 3 bits active when read from (PI_STATUS_REG - read) - * Bit 0: DMA busy - set when DMA is in progress - * Bit 1: IO busy - set when IO is in progress - * Bit 2: Error - set when CPU issues IO request while DMA is busy + * Bit 0: DMA busy - set when DMA is in progress + * Bit 1: IO busy - set when IO is in progress + * Bit 2: Error - set when CPU issues IO request while DMA is busy */ -#define PI_STATUS_ERROR 0x04 -#define PI_STATUS_IO_BUSY 0x02 -#define PI_STATUS_DMA_BUSY 0x01 +#define PI_STATUS_DMA_BUSY (1 << 0) +#define PI_STATUS_IO_BUSY (1 << 1) +#define PI_STATUS_ERROR (1 << 2) /* PI status register has 2 bits active when written to: - * Bit 0: When set, reset PIC - * Bit 1: When set, clear interrupt flag + * Bit 0: When set, reset PIC + * Bit 1: When set, clear interrupt flag * The values of the two bits can be ORed together to both reset PIC and * clear interrupt at the same time. * * Note: - * - The PIC does generate an interrupt at the end of each DMA. CPU - * needs to clear the interrupt flag explicitly (from an interrupt - * handler) by writing into the STATUS register with bit 1 set. + * - The PIC does generate an interrupt at the end of each DMA. CPU + * needs to clear the interrupt flag explicitly (from an interrupt + * handler) by writing into the STATUS register with bit 1 set. * - * - When a DMA completes, the interrupt flag is set. CPU can issue - * another request even while the interrupt flag is set (as long as - * PIC is idle). However, it is the CPU's responsibility for - * maintaining accurate correspondence between DMA completions and - * interrupts. + * - When a DMA completes, the interrupt flag is set. CPU can issue + * another request even while the interrupt flag is set (as long as + * PIC is idle). However, it is the CPU's responsibility for + * maintaining accurate correspondence between DMA completions and + * interrupts. * - * - When PIC is reset, if PIC happens to be busy, an interrupt will - * be generated as PIC returns to idle. Otherwise, no interrupt will - * be generated and PIC remains idle. + * - When PIC is reset, if PIC happens to be busy, an interrupt will + * be generated as PIC returns to idle. Otherwise, no interrupt will + * be generated and PIC remains idle. */ + /* - * Values to clear interrupt/reset PIC (PI_STATUS_REG - write) + * PI_STATUS_REG: write bits */ -#define PI_STATUS_RESET 0x01 -#define PI_SET_RESET PI_STATUS_RESET +#define PI_STATUS_RESET (1 << 0) +#define PI_SET_RESET PI_STATUS_RESET -#define PI_STATUS_CLR_INTR 0x02 -#define PI_CLR_INTR PI_STATUS_CLR_INTR +#define PI_STATUS_CLR_INTR (1 << 1) +#define PI_CLR_INTR PI_STATUS_CLR_INTR -#define PI_DMA_BUFFER_SIZE 128 +#define PI_DMA_BUFFER_SIZE 128 -#define PI_DOM1_ADDR1 0x06000000 /* to 0x07FFFFFF */ -#define PI_DOM1_ADDR2 0x10000000 /* to 0x1FBFFFFF */ -#define PI_DOM1_ADDR3 0x1FD00000 /* to 0x7FFFFFFF */ -#define PI_DOM2_ADDR1 0x05000000 /* to 0x05FFFFFF */ -#define PI_DOM2_ADDR2 0x08000000 /* to 0x0FFFFFFF */ +#define PI_DOM1_ADDR1 0x06000000 /* to 0x07FFFFFF */ +#define PI_DOM1_ADDR2 0x10000000 /* to 0x1FBFFFFF */ +#define PI_DOM1_ADDR3 0x1FD00000 /* to 0x7FFFFFFF */ +#define PI_DOM2_ADDR1 0x05000000 /* to 0x05FFFFFF */ +#define PI_DOM2_ADDR2 0x08000000 /* to 0x0FFFFFFF */ - -/************************************************************************* +/** * RDRAM Interface (RI) Registers */ -#define RI_BASE_REG 0x04700000 +#define RI_BASE_REG 0x04700000 /* RI mode (R/W): [1:0] operating mode, [2] stop T active, [3] stop R active */ -#define RI_MODE_REG (RI_BASE_REG+0x00) +#define RI_MODE_REG (RI_BASE_REG + 0x00) /* RI config (R/W): [5:0] current control input, [6] current control enable */ -#define RI_CONFIG_REG (RI_BASE_REG+0x04) +#define RI_CONFIG_REG (RI_BASE_REG + 0x04) /* RI current load (W): [] any write updates current control register */ -#define RI_CURRENT_LOAD_REG (RI_BASE_REG+0x08) +#define RI_CURRENT_LOAD_REG (RI_BASE_REG + 0x08) /* RI select (R/W): [2:0] receive select, [2:0] transmit select */ -#define RI_SELECT_REG (RI_BASE_REG+0x0C) +#define RI_SELECT_REG (RI_BASE_REG + 0x0C) /* RI refresh (R/W): [7:0] clean refresh delay, [15:8] dirty refresh delay, - * [16] refresh bank, [17] refresh enable - * [18] refresh optimize + * [16] refresh bank, [17] refresh enable + * [18] refresh optimize */ -#define RI_REFRESH_REG (RI_BASE_REG+0x10) -#define RI_COUNT_REG RI_REFRESH_REG +#define RI_REFRESH_REG (RI_BASE_REG + 0x10) +#define RI_COUNT_REG RI_REFRESH_REG /* RI latency (R/W): [3:0] DMA latency/overlap */ -#define RI_LATENCY_REG (RI_BASE_REG+0x14) +#define RI_LATENCY_REG (RI_BASE_REG + 0x14) /* RI error (R): [0] nack error, [1] ack error */ -#define RI_RERROR_REG (RI_BASE_REG+0x18) +#define RI_RERROR_REG (RI_BASE_REG + 0x18) /* RI error (W): [] any write clears all error bits */ -#define RI_WERROR_REG (RI_BASE_REG+0x1C) +#define RI_WERROR_REG (RI_BASE_REG + 0x1C) - -/************************************************************************* - * Serial Interface (SI) Registers +/** + * Serial Interface (SI) Registers */ -#define SI_BASE_REG 0x04800000 +#define SI_BASE_REG 0x04800000 /* SI DRAM address (R/W): [23:0] starting RDRAM address */ -#define SI_DRAM_ADDR_REG (SI_BASE_REG+0x00) /* R0: DRAM address */ +#define SI_DRAM_ADDR_REG (SI_BASE_REG + 0x00) -/* SI address read 64B (W): [] any write causes a 64B DMA write */ -#define SI_PIF_ADDR_RD64B_REG (SI_BASE_REG+0x04) /* R1: 64B PIF->DRAM */ +/* SI address read 64B (W): [] write begins a 64B DMA write PIF RAM -> RDRAM */ +#define SI_PIF_ADDR_RD64B_REG (SI_BASE_REG + 0x04) -/* Address SI_BASE_REG + (0x08, 0x0c, 0x14) are reserved */ +/* Address SI_BASE_REG + (0x08, 0x0C, 0x14) are reserved */ -/* SI address write 64B (W): [] any write causes a 64B DMA read */ -#define SI_PIF_ADDR_WR64B_REG (SI_BASE_REG+0x10) /* R4: 64B DRAM->PIF */ +/* SI address write 64B (W): [] write begins a 64B DMA read RDRAM -> PIF RAM */ +#define SI_PIF_ADDR_WR64B_REG (SI_BASE_REG + 0x10) -/* - * SI status (W): [] any write clears interrupt - * (R): [0] DMA busy, [1] IO read busy, [2] reserved - * [3] DMA error, [12] interrupt +/* SI status (R/W): [] any write clears interrupt */ +#define SI_STATUS_REG (SI_BASE_REG + 0x18) + +/* + * SI_STATUS_REG: read bits */ -#define SI_STATUS_REG (SI_BASE_REG+0x18) /* R6: Status */ +#define SI_STATUS_DMA_BUSY (1 << 0) /* DMA in progress */ +#define SI_STATUS_RD_BUSY (1 << 1) /* IO access in progress */ +#define SI_STATUS_DMA_ERROR (1 << 3) /* Overlapping DMA requests */ +#define SI_STATUS_INTERRUPT (1 << 12) /* Interrupt is set */ -/* SI status register has the following bits active: - * 0: DMA busy - set when DMA is in progress - * 1: IO busy - set when IO access is in progress - * 3: DMA error - set when there are overlapping DMA requests - * 12: Interrupt - Interrupt set - */ -#define SI_STATUS_DMA_BUSY 0x0001 -#define SI_STATUS_RD_BUSY 0x0002 -#define SI_STATUS_DMA_ERROR 0x0008 -#define SI_STATUS_INTERRUPT 0x1000 - -/************************************************************************* +/** * Development Board GIO Control Registers */ @@ -862,19 +833,18 @@ The Indy development board use cartridge domain 1: /* Host to Game Interrupt */ #define GIO_CART_INTR_REG (GIO_BASE_REG+0x800) - -/************************************************************************* +/** * Common macros */ #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) -#define IO_READ(addr) (*(vu32 *)PHYS_TO_K1(addr)) -#define IO_WRITE(addr,data) (*(vu32 *)PHYS_TO_K1(addr)=(u32)(data)) -#define RCP_STAT_PRINT \ - rmonPrintf("current=%x start=%x end=%x dpstat=%x spstat=%x\n", \ - IO_READ(DPC_CURRENT_REG), \ - IO_READ(DPC_START_REG), \ - IO_READ(DPC_END_REG), \ - IO_READ(DPC_STATUS_REG), \ +#define IO_READ(addr) (*(vu32*)PHYS_TO_K1(addr)) +#define IO_WRITE(addr,data) (*(vu32*)PHYS_TO_K1(addr)=(u32)(data)) +#define RCP_STAT_PRINT \ + rmonPrintf("current=%x start=%x end=%x dpstat=%x spstat=%x\n", \ + IO_READ(DPC_CURRENT_REG), \ + IO_READ(DPC_START_REG), \ + IO_READ(DPC_END_REG), \ + IO_READ(DPC_STATUS_REG), \ IO_READ(SP_STATUS_REG)) #endif diff --git a/include/PR/sptask.h b/include/PR/sptask.h index 46dd0e2c..3e626e5e 100644 --- a/include/PR/sptask.h +++ b/include/PR/sptask.h @@ -1,73 +1,76 @@ -#ifndef _ULTRA64_SPTASK_H_ -#define _ULTRA64_SPTASK_H_ +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ -/* Task Types */ -#define M_GFXTASK 1 -#define M_AUDTASK 2 -#define M_VIDTASK 3 -#define M_HVQTASK 6 -#define M_HVQMTASK 7 +/************************************************************************** + * + * $Revision: 1.9 $ + * $Date: 1998/03/05 06:40:29 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/sptask.h,v $ + * + **************************************************************************/ -#if (defined(F3DEX_GBI) || defined(F3DLP_GBI) || defined(F3DEX_GBI_2)) -#define OS_YIELD_DATA_SIZE 0xc00 -#else -#define OS_YIELD_DATA_SIZE 0x900 -#endif -#define OS_YIELD_AUDIO_SIZE 0x400 +#ifndef _SPTASK_H_ +#define _SPTASK_H_ -/* Flags */ -#define M_TASK_FLAG0 1 -#define M_TASK_FLAG1 2 -#if defined(VERSION_SH) || defined(VERSION_CN) -#define M_TASK_FLAG2 4 +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { #endif -/* SpStatus */ -#define SPSTATUS_CLEAR_HALT 0x00000001 -#define SPSTATUS_SET_HALT 0x00000002 -#define SPSTATUS_CLEAR_BROKE 0x00000004 -#define SPSTATUS_CLEAR_INTR 0x00000008 -#define SPSTATUS_SET_INTR 0x00000010 -#define SPSTATUS_CLEAR_SSTEP 0x00000020 -#define SPSTATUS_SET_SSTEP 0x00000040 -#define SPSTATUS_CLEAR_INTR_ON_BREAK 0x00000080 -#define SPSTATUS_SET_INTR_ON_BREAK 0x00000100 -#define SPSTATUS_CLEAR_SIGNAL0 0x00000200 -#define SPSTATUS_SET_SIGNAL0 0x00000400 -#define SPSTATUS_CLEAR_SIGNAL1 0x00000800 -#define SPSTATUS_SET_SIGNAL1 0x00001000 -#define SPSTATUS_CLEAR_SIGNAL2 0x00002000 -#define SPSTATUS_SET_SIGNAL2 0x00004000 -#define SPSTATUS_CLEAR_SIGNAL3 0x00008000 -#define SPSTATUS_SET_SIGNAL3 0x00010000 -#define SPSTATUS_CLEAR_SIGNAL4 0x00020000 -#define SPSTATUS_SET_SIGNAL4 0x00040000 -#define SPSTATUS_CLEAR_SIGNAL5 0x00080000 -#define SPSTATUS_SET_SIGNAL5 0x00100000 -#define SPSTATUS_CLEAR_SIGNAL6 0x00200000 -#define SPSTATUS_SET_SIGNAL6 0x00800000 -#define SPSTATUS_CLEAR_SIGNAL7 0x01000000 -#define SPSTATUS_SET_SIGNAL7 0x02000000 +#include -#define SPSTATUS_HALT 0x0001 -#define SPSTATUS_BROKE 0x0002 -#define SPSTATUS_DMA_BUSY 0x0004 -#define SPSTATUS_DMA_FULL 0x0008 -#define SPSTATUS_IO_FULL 0x0010 -#define SPSTATUS_SINGLE_STEP 0x0020 -#define SPSTATUS_INTERRUPT_ON_BREAK 0x0040 -#define SPSTATUS_SIGNAL0_SET 0x0080 -#define SPSTATUS_SIGNAL1_SET 0x0100 -#define SPSTATUS_SIGNAL2_SET 0x0200 -#define SPSTATUS_SIGNAL3_SET 0x0400 -#define SPSTATUS_SIGNAL4_SET 0x0800 -#define SPSTATUS_SIGNAL5_SET 0x1000 -#define SPSTATUS_SIGNAL6_SET 0x2000 -#define SPSTATUS_SIGNAL7_SET 0x4000 +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) -/* Types */ -/* Types */ +/************************************************************************** + * + * Type definitions + * + */ +/* + * Task List Structure. + * + * Things an app might pass to the SP via the task list. + * Not every task ucode would need/use every field, but + * + * - type (audio, gfx, video, ...) + * - flags + * - wait for DP to drain before running new task + * - SEE BIT DEFINITIONS UNDER "Task Flags field" + * - pointer to boot ucode + * - size of boot ucode + * - pointer to ucode + * - size of ucode + * - pointer to initial DMEM data + * - size of initial DMEM data + * - pointer to DRAM stack + * - size of DRAM stack (max) + * - pointer to output buffer + * - pointer to store output buffer length + * - generic data pointer (for display list, etc.) + * - generic data length (for display list, etc.) + * - pointer to buffer where to store saved DMEM (in yield case) + * - size of buffer to store saved DMEM. + * + * IMPORTANT!!! Watch alignment issues. + * + * IMPORTANT!!! Watch data cache issues. The RCP may write data into the + * dram_stack, output_buff, output_buff_size, and the yield_data_ptr areas. + * These buffers should be cache aligned and use the entire line (16 bytes) to + * avoid corruption by writebacks by the CPU (cache tearing). + * + * IMPORTANT!!! all addresses are virtual addresses. Library does + * any necessary translation. + * + */ typedef struct { /*0x00*/ u32 type; @@ -101,16 +104,77 @@ typedef union { } OSTask; typedef u32 OSYieldResult; +#endif /* _LANGUAGE_C */ -/* Functions */ +/* + * Task Flags field + */ +#define OS_TASK_YIELDED 0x0001 +#define OS_TASK_DP_WAIT 0x0002 +#define OS_TASK_LOADABLE 0x0004 +#define OS_TASK_SP_ONLY 0x0008 +#define OS_TASK_USR0 0x0010 +#define OS_TASK_USR1 0x0020 +#define OS_TASK_USR2 0x0040 +#define OS_TASK_USR3 0x0080 + +/* + * Size of Yield buffer. The taskHdrPtr->t.yield_data_ptr must point to a + * buffer of this size. (The size is in bytes). ONLY If the task will NEVER + * yield it may be a null pointer. The buffer must be aligned to a 64 bit + * boundary. The taskHdrPtr->t.yield_data_ptr must be set to point to the + * buffer BEFORE the task is started. + */ +#define OS_YIELD_DATA_SIZE_EX 0xC00 +#if (defined(F3DEX_GBI) || defined(F3DLP_GBI) || defined(F3DEX_GBI_2)) +#define OS_YIELD_DATA_SIZE OS_YIELD_DATA_SIZE_EX +#else +#define OS_YIELD_DATA_SIZE 0x900 +#endif +#define OS_YIELD_AUDIO_SIZE 0x400 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + +/* + * this macro simulates atomic action. + */ #define osSpTaskStart(p) \ osSpTaskLoad(p); \ osSpTaskStartGo(p); -void osSpTaskLoad(OSTask *task); -void osSpTaskStartGo(OSTask *task); -void osSpTaskYield(void); -OSYieldResult osSpTaskYielded(OSTask *task); +/************************************************************************** + * + * Extern variables + * + */ + +/************************************************************************** + * + * Function prototypes + * + */ + +/* + * break this up into two steps for debugging. + */ +extern void osSpTaskLoad(OSTask *task); +extern void osSpTaskStartGo(OSTask *task); + +extern void osSpTaskYield(void); +extern OSYieldResult osSpTaskYielded(OSTask *task); + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} #endif + +#endif /* !_SPTASK_H */ diff --git a/include/PR/ultratypes.h b/include/PR/ultratypes.h index 425b7a9e..69f62ac7 100644 --- a/include/PR/ultratypes.h +++ b/include/PR/ultratypes.h @@ -1,23 +1,72 @@ -#ifndef _ULTRA64_TYPES_H_ -#define _ULTRA64_TYPES_H_ +#ifndef _ULTRATYPES_H_ +#define _ULTRATYPES_H_ -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) -#ifndef NULL -#define NULL (void *)0 -#endif +/************************************************************************** + * * + * Copyright (C) 1995, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ -#define TRUE 1 -#define FALSE 0 +/************************************************************************* + * + * File: ultratypes.h + * + * This file contains various types used in Ultra64 interfaces. + * + * $Revision: 1.6 $ + * $Date: 1997/12/17 04:02:06 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/ultratypes.h,v $ + * + **************************************************************************/ + + +/********************************************************************** + * General data types for R4300 + */ + +#ifndef _LANGUAGE_ASSEMBLY typedef signed char s8; typedef unsigned char u8; typedef signed short int s16; typedef unsigned short int u16; typedef signed int s32; typedef unsigned int u32; + +typedef float f32; +typedef double f64; + +#ifdef TARGET_N64 typedef signed long long int s64; typedef unsigned long long int u64; +typedef u32 size_t; +typedef s32 ssize_t; +typedef u32 uintptr_t; +typedef s32 intptr_t; +typedef s32 ptrdiff_t; + +typedef s8 int8_t; +typedef u8 uint8_t; +typedef s16 int16_t; +typedef u16 uint16_t; +typedef s32 int32_t; +typedef u32 uint32_t; +typedef s64 int64_t; +typedef u64 uint64_t; +#else +#include +#include +typedef ptrdiff_t ssize_t; +typedef int64_t s64; +typedef uint64_t u64; +#endif typedef volatile u8 vu8; typedef volatile u16 vu16; @@ -27,22 +76,21 @@ typedef volatile s8 vs8; typedef volatile s16 vs16; typedef volatile s32 vs32; typedef volatile s64 vs64; +#endif // _LANGUAGE_ASSEMBLY -typedef float f32; -typedef double f64; - -#ifdef TARGET_N64 -typedef u32 size_t; -typedef s32 ssize_t; -typedef u32 uintptr_t; -typedef s32 intptr_t; -typedef s32 ptrdiff_t; -#else -#include -#include -typedef ptrdiff_t ssize_t; +/************************************************************************* + * Common definitions + */ +#ifndef TRUE +#define TRUE 1 #endif +#ifndef FALSE +#define FALSE 0 #endif +#ifndef NULL +#define NULL (void *)0 #endif + +#endif /* _ULTRATYPES_H_ */ diff --git a/include/gcc/math.h b/include/gcc/math.h new file mode 100644 index 00000000..3e93ceb1 --- /dev/null +++ b/include/gcc/math.h @@ -0,0 +1 @@ +// Nothing needed here diff --git a/include/libc/stdarg.h b/include/gcc/stdarg.h similarity index 100% rename from include/libc/stdarg.h rename to include/gcc/stdarg.h diff --git a/include/libc/stddef.h b/include/gcc/stddef.h similarity index 100% rename from include/libc/stddef.h rename to include/gcc/stddef.h diff --git a/include/libc/stdio.h b/include/gcc/stdio.h similarity index 100% rename from include/libc/stdio.h rename to include/gcc/stdio.h diff --git a/include/libc/stdlib.h b/include/gcc/stdlib.h similarity index 100% rename from include/libc/stdlib.h rename to include/gcc/stdlib.h diff --git a/include/libc/string.h b/include/gcc/string.h similarity index 100% rename from include/libc/string.h rename to include/gcc/string.h diff --git a/include/libc/math.h b/include/libc/math.h deleted file mode 100644 index 8cea459b..00000000 --- a/include/libc/math.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MATH_H -#define MATH_H - -#define M_PI 3.14159265358979323846 - -float sinf(float); -double sin(double); -float cosf(float); -double cos(double); - -float sqrtf(float); - -#endif diff --git a/include/macros.h b/include/macros.h index 57d59218..803fc6c1 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,18 +1,28 @@ #ifndef MACROS_H #define MACROS_H +// Check for egcs compiler +#if defined (__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 91) +#define EGCS_GCC +#endif + +#ifndef _LANGUAGE_ASSEMBLY #include "platform_info.h" +// Since we are using both compilers to match iQue, ignore these errors. +#ifndef EGCS_GCC + #ifndef __sgi #define GLOBAL_ASM(...) #endif #if !defined(__sgi) && (!defined(NON_MATCHING) || !defined(AVOID_UB)) -// asm-process isn't supported outside of IDO, and undefined behavior causes -// crashes. +// asm-process isn't supported outside of IDO, and undefined behavior causes crashes. #error Matching build is only possible on IDO; please build with NON_MATCHING=1. #endif +#endif + #define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0])) #define GLUE(a, b) a ## b @@ -46,14 +56,14 @@ #endif // Align to 8-byte boundary for DMA requirements -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(EGCS_GCC) #define ALIGNED8 __attribute__((aligned(8))) #else #define ALIGNED8 #endif // Align to 16-byte boundary for audio lib requirements -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(EGCS_GCC) #define ALIGNED16 __attribute__((aligned(16))) #else #define ALIGNED16 @@ -88,4 +98,6 @@ #define FORCE_BSS #endif +#endif + #endif // MACROS_H diff --git a/include/macros.inc b/include/macros.inc index bcbe5f17..94c6caac 100644 --- a/include/macros.inc +++ b/include/macros.inc @@ -1,17 +1,18 @@ -#ifndef VERSION_CN -.set gp=64 +#ifdef _LANGUAGE_ASSEMBLY +#undef _LANGUAGE_C #endif -.equ K0BASE, 0x80000000 -.equ K1BASE, 0xA0000000 -.equ K2BASE, 0xC0000000 - .macro glabel label .global \label .balign 4 \label: .endm +.macro gsymbol sym addr +.global \sym +.equ \sym, \addr +.endm + .macro .word32 x .word \x .endm diff --git a/include/segments.h b/include/segments.h index 65f1fc46..6c1be3d7 100644 --- a/include/segments.h +++ b/include/segments.h @@ -21,7 +21,7 @@ #ifndef USE_EXT_RAM /* Default: Runs out of memory quickly when importing custom assets. */ -#define RDRAM_END 0x80400000 +#define SEG_RAM_END 0x80400000 #define SEG_POOL_START SEG_START #define SEG_POOL_SIZE 0x165000 @@ -35,7 +35,7 @@ #define SEG_ENGINE 0x80378800 #endif -#define SEG_FRAMEBUFFERS (RDRAM_END - SEG_FRAMEBUFFERS_SIZE) +#define SEG_FRAMEBUFFERS (SEG_RAM_END - SEG_FRAMEBUFFERS_SIZE) #else /* Use Expansion Pak space for pool. */ @@ -45,16 +45,16 @@ */ #ifdef VERSION_CN -#define RDRAM_END 0x807C0000 // iQue has stuff like EEPROM mapped at 807C0000 onwards. TODO: Code this using osMemSize +#define SEG_RAM_END 0x807C0000 // iQue has stuff like EEPROM mapped at 807C0000 onwards. TODO: Code this using osMemSize #else -#define RDRAM_END 0x80800000 +#define SEG_RAM_END 0x80800000 #endif #define SEG_BUFFERS SEG_START #define SEG_ENGINE ((u32) &_engineSegmentStart) #define SEG_FRAMEBUFFERS ((u32) &_framebuffersSegmentNoloadStart) #define SEG_POOL_START ((u32) &_framebuffersSegmentNoloadEnd) -#define SEG_POOL_END RDRAM_END +#define SEG_POOL_END SEG_RAM_END #define SEG_POOL_END_4MB 0x80400000 // For the error message screen enhancement. #endif diff --git a/include/sys/asm.h b/include/sys/asm.h new file mode 100644 index 00000000..445a2bf3 --- /dev/null +++ b/include/sys/asm.h @@ -0,0 +1,72 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO Co,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO Co,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO Co,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/07/06 13:21:13 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#ifndef __ASM_H__ +#define __ASM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define _MIPS_ISA_MIPS1 1 /* R2/3K */ +#define _MIPS_ISA_MIPS2 2 /* R4K/6K */ +#define _MIPS_ISA_MIPS3 3 /* R4K */ +#define _MIPS_ISA_MIPS4 4 /* TFP */ + +#define _MIPS_SIM_ABI32 1 /* MIPS MSIG calling convention */ +#define _MIPS_SIM_NABI32 2 /* MIPS new 32-bit abi */ + /* NABI32 is 64bit calling convention but 32bit type sizes) */ +#define _MIPS_SIM_ABI64 3 /* MIPS 64 calling convention */ + +#define LEAF(x) \ + .globl x; \ + .ent x,0; \ +x:; \ + .frame sp,0,ra + +#define XLEAF(x) \ + .global x; + +#define END(proc) \ + .end proc + +#define ABS(x, y) \ + .globl x; \ + x = y + +#define EXPORT(x) \ + .globl x; \ +x: +/* +#define WEAK(x, y) \ + .weak x; \ + .set x,y; +*/ + +#define WEAK(x, y) + +#define STAY1(stmnt) .set noreorder; stmnt; .set reorder; +#define STAY2(stmnt, arg1) .set noreorder; stmnt, arg1; .set reorder; +#define STAY3(stmnt, arg1, arg2) .set noreorder; stmnt, arg1, arg2; .set reorder; +#define NOP .set noreorder; nop; .set reorder; +#define CACHE(op, reg) .set noreorder; cache op, reg; .set reorder; + +#ifdef __cplusplus +} +#endif + +#endif /* !__ASM_H__ */ diff --git a/include/sys/fpregdef.h b/include/sys/fpregdef.h new file mode 100644 index 00000000..e69de29b diff --git a/include/sys/regdef.h b/include/sys/regdef.h new file mode 100644 index 00000000..ac9c109a --- /dev/null +++ b/include/sys/regdef.h @@ -0,0 +1,187 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO Co,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO Co,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO Co,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/07/06 13:21:13 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#ifndef __REGDEF_H__ +#define __REGDEF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef mips + +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define zero $0 +#define AT $at +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define ta0 $12 +#define t5 $13 +#define ta1 $13 +#define t6 $14 +#define ta2 $14 +#define t7 $15 +#define ta3 $15 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 +#define t9 $25 +#define jp $25 +#define k0 $26 +#define k1 $27 +#define gp $28 +#define sp $29 +#define fp $30 +#define s8 $30 +#define ra $31 +#endif + +#if (_MIPS_SIM == _MIPS_SIM_ABI64) +#define zero $0 +#define AT $at +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define a4 $8 +#define ta0 $8 +#define a5 $9 +#define ta1 $9 +#define a6 $10 +#define ta2 $10 +#define a7 $11 +#define ta3 $11 +#define t0 $12 +#define t1 $13 +#define t2 $14 +#define t3 $15 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 +#define t9 $25 +#define jp $25 +#define k0 $26 +#define k1 $27 +#define gp $28 +#define sp $29 +#define fp $30 +#define s8 $30 +#define ra $31 +#endif + +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define fv0 $f0 +#define fv0f $f1 +#define fv1 $f2 +#define fv1f $f3 +#define fa0 $f12 +#define fa0f $f13 +#define fa1 $f14 +#define fa1f $f15 +#define ft0 $f4 +#define ft0f $f5 +#define ft1 $f6 +#define ft1f $f7 +#define ft2 $f8 +#define ft2f $f9 +#define ft3 $f10 +#define ft3f $f11 +#define ft4 $f16 +#define ft4f $f17 +#define ft5 $f18 +#define ft5f $f19 +#define fs0 $f20 +#define fs0f $f21 +#define fs1 $f22 +#define fs1f $f23 +#define fs2 $f24 +#define fs2f $f25 +#define fs3 $f26 +#define fs3f $f27 +#define fs4 $f28 +#define fs4f $f29 +#define fs5 $f30 +#define fs5f $f31 +#endif + +#if (_MIPS_SIM == _MIPS_SIM_ABI64) +#define fv0 $f0 +#define fv1 $f2 +#define fa0 $f12 +#define fa1 $f13 +#define fa2 $f14 +#define fa3 $f15 +#define fa4 $f16 +#define fa5 $f17 +#define fa6 $f18 +#define fa7 $f19 +#define ft0 $f4 +#define ft1 $f5 +#define ft2 $f6 +#define ft3 $f7 +#define ft4 $f8 +#define ft5 $f9 +#define ft6 $f10 +#define ft7 $f11 +#define ft8 $f20 +#define ft9 $f21 +#define ft10 $f22 +#define ft11 $f23 +#define ft12 $f1 +#define ft13 $f3 +#define fs0 $f24 +#define fs1 $f25 +#define fs2 $f26 +#define fs3 $f27 +#define fs4 $f28 +#define fs5 $f29 +#define fs6 $f30 +#define fs7 $f31 +#endif + +#define fcr31 $31 + +#endif /* mips */ + +#ifdef __cplusplus +} +#endif + +#endif /* !__REGDEF_H__ */ diff --git a/include/text_strings.h.in b/include/text_strings.h.in index a1f1ae3e..487aeda7 100644 --- a/include/text_strings.h.in +++ b/include/text_strings.h.in @@ -407,89 +407,6 @@ #define TEXT_LETS_HAVE_CAKE_DE _("Laßt uns einen leckeren Kuchen backen...") #define TEXT_FOR_MARIO_DE _("...fÃŒr Mario...") -/** - * Course Table names for Score Menu Save view - */ -#define TEXT_MENU_BOB _(" 1 BOB-OMB BATTLEFIELD") -#define TEXT_MENU_WF _(" 2 WHOMP'S FORTRESS") -#define TEXT_MENU_JRB _(" 3 JOLLY ROGER BAY") -#define TEXT_MENU_CCM _(" 4 COOL, COOL MOUNTAIN") -#define TEXT_MENU_BBH _(" 5 BIG BOO'S HAUNT") -#define TEXT_MENU_HMC _(" 6 HAZY MAZE CAVE") -#define TEXT_MENU_LLL _(" 7 LETHAL LAVA LAND") -#define TEXT_MENU_SSL _(" 8 SHIFTING SAND LAND") -#define TEXT_MENU_DDD _(" 9 DIRE, DIRE DOCKS") -#define TEXT_MENU_SL _("10 SNOWMAN'S LAND") -#define TEXT_MENU_WDW _("11 WET-DRY WORLD") -#define TEXT_MENU_TTM _("12 TALL, TALL MOUNTAIN") -#define TEXT_MENU_THI _("13 TINY-HUGE ISLAND") -#define TEXT_MENU_TTC _("14 TICK TOCK CLOCK") -#define TEXT_MENU_RR _("15 RAINBOW RIDE") -#define TEXT_MENU_BITDW _(" BOWSER IN THE DARK WORLD") -#define TEXT_MENU_BITFS _(" BOWSER IN THE FIRE SEA") -#define TEXT_MENU_BITS _(" BOWSER IN THE SKY") -#define TEXT_MENU_PSS _(" THE PRINCESS'S SECRET SLIDE") -#define TEXT_MENU_COTMC _(" CAVERN OF THE METAL CAP") -#define TEXT_MENU_TOTWC _(" TOWER OF THE WING CAP") -#define TEXT_MENU_VCUTM _(" VANISH CAP UNDER THE MOAT") -#define TEXT_MENU_WMOTR _(" WING MARIO OVER THE RAINBOW") -#define TEXT_MENU_SA _(" THE SECRET AQUARIUM") -#define TEXT_MENU_NONE _("") -#define TEXT_MENU_STARS _(" CASTLE SECRET STARS") - -#define TEXT_MENU_BOB_FR _(" 1 BATAILLE DE BOB-OMB") -#define TEXT_MENU_WF_FR _(" 2 FORTERESSE DE WHOMP") -#define TEXT_MENU_JRB_FR _(" 3 BAIE DES PIRATES") -#define TEXT_MENU_CCM_FR _(" 4 MONTAGNE GLA-GLA") -#define TEXT_MENU_BBH_FR _(" 5 MANOIR DE BIG BOO") -#define TEXT_MENU_HMC_FR _(" 6 CAVERNE BRUMEUSE") -#define TEXT_MENU_LLL_FR _(" 7 LAVES FATALES") -#define TEXT_MENU_SSL_FR _(" 8 SABLES TROP MOUVANTS") -#define TEXT_MENU_DDD_FR _(" 9 AFFREUX BASSIN") -#define TEXT_MENU_SL_FR _("10 CHEZ LE ROI DES NEIGES") -#define TEXT_MENU_WDW_FR _("11 MONDE TREMPE-SECHE") -#define TEXT_MENU_TTM_FR _("12 TROP HAUTE MONTAGNE") -#define TEXT_MENU_THI_FR _("13 ILE GRANDS-PETITS") -#define TEXT_MENU_TTC_FR _("14 HORLOGE TIC-TAC") -#define TEXT_MENU_RR_FR _("15 COURSE ARC-EN-CIEL") -#define TEXT_MENU_BITDW_FR _(" BOWSER DES TENEBRES") -#define TEXT_MENU_BITFS_FR _(" BOWSER DES LAVES") -#define TEXT_MENU_BITS_FR _(" BOWSER DES CIEUX") -#define TEXT_MENU_PSS_FR _(" GLISSADE DE LA PRINCESSE") -#define TEXT_MENU_COTMC_FR _(" MINE DES CASQUETTES-METAL") -#define TEXT_MENU_TOTWC_FR _(" INTERRUPTEUR DE LA TOUR AILEE") -#define TEXT_MENU_VCUTM_FR _(" INVISIBLE SOUS LES DOUVES") -#define TEXT_MENU_WMOTR_FR _(" AU-DELA DE L'ARC-EN-CIEL") -#define TEXT_MENU_SA_FR _(" AQUARIUM SECRET") -#define TEXT_MENU_NONE_FR _("") -#define TEXT_MENU_STARS_FR _(" ETOILES SECRETES") - -#define TEXT_MENU_BOB_DE _(" 1 BOB-OMBS BOMBENBERG") -#define TEXT_MENU_WF_DE _(" 2 WUMMPS WUCHTWALL") -#define TEXT_MENU_JRB_DE _(" 3 PIRATENBUCHT PANIK") -#define TEXT_MENU_CCM_DE _(" 4 BIBBERBERG BOB") -#define TEXT_MENU_BBH_DE _(" 5 BIG BOOS BURG") -#define TEXT_MENU_HMC_DE _(" 6 GRÜNE GIFTGROTTE") -#define TEXT_MENU_LLL_DE _(" 7 LAVA LAGUNE") -#define TEXT_MENU_SSL_DE _(" 8 WOBIWABA WÜSTE") -#define TEXT_MENU_DDD_DE _(" 9 WILDE WASSERWERFT") -#define TEXT_MENU_SL_DE _("10 FROSTBEULEN FRUST") -#define TEXT_MENU_WDW_DE _("11 ATLANTIS AQUARIA") -#define TEXT_MENU_TTM_DE _("12 FLIEGENPILZ FIASKO") -#define TEXT_MENU_THI_DE _("13 GULLIVER GUMBA") -#define TEXT_MENU_TTC_DE _("14 TICK TACK TRAUMA") -#define TEXT_MENU_RR_DE _("15 REGENBOGEN RASEREI") -#define TEXT_MENU_BITDW_DE _(" BOWSERS SCHATTENWELT") -#define TEXT_MENU_BITFS_DE _(" BOWSERS LAVASEE") -#define TEXT_MENU_BITS_DE _(" BOWSERS LUFTSCHLOSS") -#define TEXT_MENU_PSS_DE _(" TOADSTOOLS RUTSCHBAHN") -#define TEXT_MENU_COTMC_DE _(" GRÜNER SCHALTERPALAST") -#define TEXT_MENU_TOTWC_DE _(" ROTER SCHALTERPALAST") -#define TEXT_MENU_VCUTM_DE _(" BLAUER SCHALTERPALAST") -#define TEXT_MENU_WMOTR_DE _(" REGENBOGEN FEUERWERK") -#define TEXT_MENU_SA_DE _(" VERSTECKTES AQUARIUM") -#define TEXT_MENU_NONE_DE _("") -#define TEXT_MENU_STARS_DE _(" GEHEIME STERNE") #endif // VERSION_EU #ifdef VERSION_CN diff --git a/include/types.h b/include/types.h index e53fb7dd..355f7fe2 100644 --- a/include/types.h +++ b/include/types.h @@ -57,6 +57,12 @@ typedef s8 RoomData; // Rooms are limited to -128 to 127. Change the type if you typedef Collision TerrainData; typedef TerrainData Vec3Terrain[3]; +#define M_GFXTASK 1 +#define M_AUDTASK 2 +#define M_VIDTASK 3 +#define M_HVQTASK 6 +#define M_HVQMTASK 7 + enum SpTaskState { SPTASK_STATE_NOT_STARTED, SPTASK_STATE_RUNNING, diff --git a/include/ultra64.h b/include/ultra64.h index 36516203..95246295 100644 --- a/include/ultra64.h +++ b/include/ultra64.h @@ -1,35 +1,34 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + *************************************************************************/ + +/************************************************************************** + * + * $Revision: 1.10 $ + * $Date: 1997/02/11 08:37:33 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/ultra64.h,v $ + * + **************************************************************************/ + #ifndef _ULTRA64_H_ #define _ULTRA64_H_ -#include - -#ifndef _LANGUAGE_C -#define _LANGUAGE_C -#endif - #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include -#include +#include +#include #endif diff --git a/lib/asm/__osDisableInt.s b/lib/asm/__osDisableInt.s deleted file mode 100644 index 22534ee9..00000000 --- a/lib/asm/__osDisableInt.s +++ /dev/null @@ -1,40 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -#include - - -.section .text, "ax" - - -glabel __osDisableInt -#ifdef VERSION_CN - la $t2, __OSGlobalIntMask - lw $t3, ($t2) - andi $t3, $t3, SR_IMASK -#endif - mfc0 $t0, C0_SR - and $t1, $t0, ~SR_IE - mtc0 $t1, C0_SR - andi $v0, $t0, SR_IE -#ifdef VERSION_CN - lw $t0, ($t2) - andi $t0, $t0, SR_IMASK - beq $t0, $t3, .Lret - lui $t2, %hi(__osRunningThread) - addiu $t2, %lo(__osRunningThread) - lw $t1, 0x118($t2) - andi $t2, $t1, SR_IMASK - and $t2, $t2, $t0 - and $t1, $t1, ~SR_IMASK - or $t1, $t1, $t2 - and $t1, $t1, ~SR_IE - mtc0 $t1, $12 - nop -#endif - nop -.Lret: - jr $ra - nop - diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s deleted file mode 100644 index 9c21048e..00000000 --- a/lib/asm/__osExceptionPreamble.s +++ /dev/null @@ -1,1183 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -#include -#include -#include - -#if defined(VERSION_EU) || defined(VERSION_SH) -#define VERSION_EU_SH -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#define VERSION_EU_SH_CN -#endif - -.section .text, "ax" - -#ifdef AVOID_UB -.set __osThreadTail, __osThreadTail_fix -#endif - -glabel __osExceptionPreamble - la $k0, __osException - jr $k0 - nop - -glabel __osException - la $k0, __osThreadSave - sd $at, 0x20($k0) - mfc0 $k1, $12 - sw $k1, 0x118($k0) - li $at, -4 - and $k1, $k1, $at - mtc0 $k1, $12 - sd $t0, 0x58($k0) - sd $t1, 0x60($k0) - sd $t2, 0x68($k0) - sw $zero, 0x18($k0) - mfc0 $t0, $13 -#ifndef VERSION_EU_SH_CN - andi $t1, $t0, 0x7c - li $t2, 0 - bne $t1, $t2, .L80326750 - nop - and $t1, $k1, $t0 - andi $t2, $t1, 0x4000 - beqz $t2, .L80326734 - nop - li $t1, 1 - lui $at, %hi(D_80334934) - b .L80326794 - sw $t1, %lo(D_80334934)($at) -.L80326734: - andi $t2, $t1, 0x2000 - beqz $t2, .L80326750 - nop - li $t1, 1 - lui $at, %hi(D_80334938) - b .L80326794 - sw $t1, %lo(D_80334938)($at) -.L80326750: - lui $at, %hi(D_80334934) - sw $zero, %lo(D_80334934)($at) - lui $at, %hi(D_80334938) -#endif - move $t0, $k0 -#ifndef VERSION_EU_SH_CN - sw $zero, %lo(D_80334938)($at) -#endif - lui $k0, %hi(__osThreadTail + 0x10) - lw $k0, %lo(__osThreadTail + 0x10)($k0) - ld $t1, 0x20($t0) - sd $t1, 0x20($k0) - ld $t1, 0x118($t0) - sd $t1, 0x118($k0) - ld $t1, 0x58($t0) - sd $t1, 0x58($k0) - ld $t1, 0x60($t0) - sd $t1, 0x60($k0) - ld $t1, 0x68($t0) - sd $t1, 0x68($k0) -#ifdef VERSION_EU_SH - lw $k1, 0x118($k0) -#else -.L80326794: -#endif -#ifndef VERSION_CN - mflo $t0 - sd $t0, 0x108($k0) - mfhi $t0 -#endif -#ifdef VERSION_EU_SH - andi $t1, $k1, 0xff00 -#endif - sd $v0, 0x28($k0) - sd $v1, 0x30($k0) - sd $a0, 0x38($k0) - sd $a1, 0x40($k0) - sd $a2, 0x48($k0) - sd $a3, 0x50($k0) - sd $t3, 0x70($k0) - sd $t4, 0x78($k0) - sd $t5, 0x80($k0) - sd $t6, 0x88($k0) - sd $t7, 0x90($k0) - sd $s0, 0x98($k0) - sd $s1, 0xa0($k0) - sd $s2, 0xa8($k0) - sd $s3, 0xb0($k0) - sd $s4, 0xb8($k0) - sd $s5, 0xc0($k0) - sd $s6, 0xc8($k0) - sd $s7, 0xd0($k0) - sd $t8, 0xd8($k0) - sd $t9, 0xe0($k0) - sd $gp, 0xe8($k0) - sd $sp, 0xf0($k0) - sd $fp, 0xf8($k0) - sd $ra, 0x100($k0) -#ifdef VERSION_EU_SH_CN -#ifdef VERSION_CN - mflo $t0 - sd $t0, 0x108($k0) - mfhi $t0 - sd $t0, 0x110($k0) - lw $k1, 0x118($k0) - andi $t1, $k1, SR_IMASK - beqz $t1, savercp - nop - la $t0, __OSGlobalIntMask - lw $t0, ($t0) - lui $at, (0xFFFFFFFF >> 16) - ori $at, (0xFFFFFFFF & 0xFFFF) - xor $t2, $t0, $at - andi $t2, $t2, SR_IMASK - or $t4, $t1, $t2 - lui $at, (~SR_IMASK >> 16) & 0xFFFF - ori $at, (~SR_IMASK & 0xFFFF) - and $t3, $k1, $at - or $t3, $t3, $t4 - sw $t3, 0x118($k0) - andi $t0, $t0, SR_IMASK - and $t1, $t1, $t0 - lui $at, (~SR_IMASK >> 16) & 0xFFFF - ori $at, (~SR_IMASK & 0xFFFF) - and $k1, $k1, $at - or $k1, $k1, $t1 -#else - beqz $t1, savercp - sd $t0, 0x110($k0) - la $t0, __OSGlobalIntMask - lw $t0, ($t0) - li $at, -1 -#ifdef VERSION_EU - xor $t0, $t0, $at -#else - xor $t2, $t0, $at -#endif - lui $at, (~SR_IMASK >> 16) & 0xFFFF -#ifdef VERSION_EU - andi $t0, $t0, SR_IMASK -#else - andi $t2, $t2, SR_IMASK -#endif - ori $at, (~SR_IMASK & 0xFFFF) -#ifdef VERSION_EU - or $t1, $t1, $t0 - and $k1, $k1, $at - or $k1, $k1, $t1 - sw $k1, 0x118($k0) -#else - or $t4, $t1, $t2 - and $t3, $k1, $at - andi $t0, $t0, SR_IMASK - or $t3, $t3, $t4 - and $t1, $t1, $t0 - and $k1, $k1, $at - sw $t3, 0x118($k0) - or $k1, $k1, $t1 -#endif -#endif - -savercp: - lui $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1) - beqz $t1, endrcp - nop - la $t0, __OSGlobalIntMask - lw $t0, ($t0) -#ifdef VERSION_CN - srl $t0, $t0, 0x10 - li $at, 0xFFFFFFFF -#else - lw $t4, 0x128($k0) - li $at, 0xFFFFFFFF - srl $t0, $t0, 0x10 -#endif - xor $t0, $t0, $at - andi $t0, $t0, 0x3f -#ifdef VERSION_CN - lw $t4, 0x128($k0) -#endif - and $t0, $t0, $t4 - or $t1, $t1, $t0 -endrcp: - sw $t1, 0x128($k0) -#else - sd $t0, 0x110($k0) -#endif - mfc0 $t0, C0_EPC - sw $t0, 0x11c($k0) - lw $t0, 0x18($k0) - beqz $t0, .L80326868 - nop - cfc1 $t0, $31 - nop - sw $t0, 0x12c($k0) - sdc1 $f0, 0x130($k0) - sdc1 $f2, 0x138($k0) - sdc1 $f4, 0x140($k0) - sdc1 $f6, 0x148($k0) - sdc1 $f8, 0x150($k0) - sdc1 $f10, 0x158($k0) - sdc1 $f12, 0x160($k0) - sdc1 $f14, 0x168($k0) - sdc1 $f16, 0x170($k0) - sdc1 $f18, 0x178($k0) - sdc1 $f20, 0x180($k0) - sdc1 $f22, 0x188($k0) - sdc1 $f24, 0x190($k0) - sdc1 $f26, 0x198($k0) - sdc1 $f28, 0x1a0($k0) - sdc1 $f30, 0x1a8($k0) -.L80326868: - mfc0 $t0, C0_CAUSE - sw $t0, 0x120($k0) -#ifndef VERSION_EU_SH_CN - lui $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1) - sw $t1, 0x128($k0) -#endif - li $t1, 2 - sh $t1, 0x10($k0) -#ifndef VERSION_EU_SH_CN - lui $t1, %hi(D_80334934) - lw $t1, %lo(D_80334934)($t1) - beqz $t1, .L803268B4 - nop - lui $t2, %hi(D_C0000008) - sw $zero, %lo(D_C0000008)($t2) - lui $a0, %hi(D_C0000000) - addiu $t2, %lo(D_C0000008) - jal kdebugserver - lw $a0, %lo(D_C0000000)($a0) - b .L80326E08 - nop -.L803268B4: - lui $t1, %hi(D_80334938) - lw $t1, %lo(D_80334938)($t1) - beqz $t1, .L80326900 - nop - lui $t2, %hi(D_C000000C) - sw $zero, %lo(D_C000000C)($t2) - lui $t1, %hi(__osRdbSendMessage) - lw $t1, %lo(__osRdbSendMessage)($t1) - addiu $t2, %lo(D_C000000C) - beqz $t1, .L803268E8 - nop - jal send_mesg - li $a0, 120 -.L803268E8: - lui $t1, %hi(__osRdbWriteOK) - lw $t1, %lo(__osRdbWriteOK)($t1) - lui $at, %hi(__osRdbWriteOK) - addi $t1, $t1, 1 - b .L80326E08 - sw $t1, %lo(__osRdbWriteOK)($at) -.L80326900: -#endif - andi $t1, $t0, CAUSE_EXCMASK - li $t2, EXC_BREAK - beq $t1, $t2, handle_break - nop - li $t2, EXC_CPU - beq $t1, $t2, handle_CpU - nop - li $t2, EXC_INT - bne $t1, $t2, panic - nop - and $s0, $k1, $t0 -next_interrupt: - andi $t1, $s0, SR_IMASK - srl $t2, $t1, 0xc - bnez $t2, .L80326944 - nop - srl $t2, $t1, 8 - addi $t2, $t2, 0x10 -.L80326944: - // TODO: Get rid of noat -.set at - lbu $t2, __osIntOffTable($t2) - lw $t2, __osIntTable($t2) -.set noat - jr $t2 - nop -#ifdef VERSION_EU_SH_CN -glabel IP6_Hdlr - li $at, ~CAUSE_IP6 - b next_interrupt - and $s0, $s0, $at -glabel IP7_Hdlr - li $at, ~CAUSE_IP7 - b next_interrupt - and $s0, $s0, $at -#endif -glabel counter - mfc0 $t1, C0_COMPARE - mtc0 $t1, C0_COMPARE -#ifdef VERSION_CN - li $a0, 24 - jal send_mesg - nop -#else - jal send_mesg - li $a0, 24 -#endif - lui $at, (~CAUSE_IP8 >> 16) & 0xFFFF - ori $at, (~CAUSE_IP8 & 0xFFFF) - b next_interrupt - and $s0, $s0, $at - -glabel cart -#ifdef VERSION_EU_SH_CN - li $at, ~CAUSE_IP4 - and $s0, $s0, $at -#endif -#ifdef VERSION_CN - la $t1, __osHwIntTable - addi $t1, $t1, 4 * 2 - lw $t2, ($t1) - beqz $t2, .L80307480 - nop - jalr $t2 - lw $sp, 4($t1) - beqz $v0, .L80307480 - nop - b redispatch - nop -.L80307480: - lui $s1, %hi(PHYS_TO_K1(MI_HW_INTR_REG)) - lw $s1, %lo(PHYS_TO_K1(MI_HW_INTR_REG))($s1) - andi $t1, $s1, 0x40 - beqz $t1, .L803074AC - nop - andi $s1, $s1, 0x3F80 - li $t1, 0 - lui $at, %hi(PHYS_TO_K1(PI_CARD_ADDR_REG)) - sw $t1, %lo(PHYS_TO_K1(PI_CARD_ADDR_REG))($at) - jal send_mesg - li $a0, 184 -.L803074AC: - andi $t1, $s1, 0x2000 - beqz $t1, .L803074D0 - nop - andi $s1, $s1, 0x1FC0 - li $t1, 0x2000 - lui $at, %hi(PHYS_TO_K1(MI_HW_INTR_REG)) - sw $t1, %lo(PHYS_TO_K1(MI_HW_INTR_REG))($at) - jal send_mesg - li $a0, 240 -.L803074D0: - andi $t1, $s1, 0x80 - beqz $t1, .L803074F4 - nop - andi $s1, $s1, 0x3F40 - li $t1, 0x4000 - lui $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG)) - sw $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at) - jal send_mesg - li $a0, 192 -.L803074F4: - andi $t1, $s1, 0x100 - beqz $t1, .L80307518 - nop - andi $s1, $s1, 0x3EC0 - lui $t1, 1 - lui $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG)) - sw $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at) - jal send_mesg - li $a0, 200 -.L80307518: - andi $t1, $s1, 0x200 - beqz $t1, .L8030753C - nop - andi $s1, $s1, 0x3DC0 - lui $t1, 4 - lui $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG)) - sw $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at) - jal send_mesg - li $a0, 208 -.L8030753C: - andi $t1, $s1, 0x400 - beqz $t1, .L80307560 - nop - andi $s1, $s1, 0x3BC0 - lui $t1, 0x10 - lui $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG)) - sw $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at) - jal send_mesg - li $a0, 216 -.L80307560: - andi $t1, $s1, 0x800 - beqz $t1, .L80307584 - nop - andi $s1, $s1, 0x37C0 - lui $t1, 0x40 - lui $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG)) - sw $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at) - jal send_mesg - li $a0, 224 -.L80307584: - b next_interrupt - nop -#else - li $t2, 4 - lui $at, %hi(__osHwIntTable) - addu $at, $at, $t2 - lw $t2, %lo(__osHwIntTable)($at) -#ifdef VERSION_EU_SH - la $sp, leoDiskStack - li $a0, 16 - beqz $t2, .L803269A4 - addiu $sp, $sp, 0xff0 -#else - beqz $t2, .L803269A4 - nop -#endif - jalr $t2 - nop -#ifdef VERSION_EU_SH - beqz $v0, .L803269A4 -#ifdef VERSION_SH - li $a0, 0x10 -#else - nop -#endif - b redispatch - nop -#endif -.L803269A4: - jal send_mesg -#ifdef VERSION_EU_SH - nop - b next_interrupt - nop -#else - li $a0, 16 - li $at, -2049 - b next_interrupt - and $s0, $s0, $at -#endif -#endif -glabel rcp -#ifdef VERSION_EU_SH - la $t0, __OSGlobalIntMask - lw $t0, ($t0) -#endif - lui $s1, %hi(PHYS_TO_K1(MI_INTR_REG)) - lw $s1, %lo(PHYS_TO_K1(MI_INTR_REG))($s1) -#ifdef VERSION_CN - la $t0, __OSGlobalIntMask - lw $t0, ($t0) -#endif -#ifdef VERSION_EU_SH_CN - srl $t0, $t0, 0x10 - and $s1, $s1, $t0 -#else - andi $s1, $s1, 0x3f -#endif - andi $t1, $s1, MI_INTR_SP - beqz $t1, vi - nop -#ifdef VERSION_CN - andi $s1, $s1, 0x3e -#endif - lui $t4, %hi(PHYS_TO_K1(SP_STATUS_REG)) - lw $t4, %lo(PHYS_TO_K1(SP_STATUS_REG))($t4) -#ifdef VERSION_CN - li $t1, SP_CLR_INTR | SP_CLR_SIG3 -#else - li $t1, SP_CLR_INTR -#endif - lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) -#ifdef VERSION_CN - sw $t1, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) - andi $t4, $t4, 0x300 - beqz $t4, sp_other_break - nop -#else - andi $t4, $t4, 0x300 - andi $s1, $s1, 0x3e - beqz $t4, sp_other_break - sw $t1, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) -#endif - jal send_mesg - li $a0, 32 - beqz $s1, no_more_rcp_ints - nop - b vi - nop -sp_other_break: - jal send_mesg - li $a0, 88 - beqz $s1, no_more_rcp_ints - nop -vi: - andi $t1, $s1, 8 - beqz $t1, ai -#ifdef VERSION_CN - nop - andi $s1, $s1, 0x37 - lui $at, %hi(PHYS_TO_K1(VI_CURRENT_REG)) -#else - lui $at, %hi(PHYS_TO_K1(VI_CURRENT_REG)) - andi $s1, $s1, 0x37 -#endif - sw $zero, %lo(PHYS_TO_K1(VI_CURRENT_REG))($at) - jal send_mesg - li $a0, 56 - beqz $s1, no_more_rcp_ints - nop -ai: - andi $t1, $s1, 4 - beqz $t1, si - nop -#ifdef VERSION_CN - andi $s1, $s1, 0x3b -#endif - li $t1, 1 - lui $at, %hi(PHYS_TO_K1(AI_STATUS_REG)) -#ifndef VERSION_CN - andi $s1, $s1, 0x3b -#endif - sw $t1, %lo(PHYS_TO_K1(AI_STATUS_REG))($at) - jal send_mesg - li $a0, 48 - beqz $s1, no_more_rcp_ints - nop -si: - andi $t1, $s1, 2 - beqz $t1, pi -#ifdef VERSION_CN - nop -#else - lui $at, %hi(PHYS_TO_K1(SI_STATUS_REG)) -#endif - andi $s1, $s1, 0x3d -#ifdef VERSION_CN - lui $at, %hi(PHYS_TO_K1(SI_STATUS_REG)) -#endif - sw $zero, %lo(PHYS_TO_K1(SI_STATUS_REG))($at) - jal send_mesg - li $a0, 40 - beqz $s1, no_more_rcp_ints - nop -pi: - andi $t1, $s1, 0x10 - beqz $t1, dp - nop -#ifdef VERSION_CN - andi $s1, $s1, 0x2f - li $t1, 2 - lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) - sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) - la $t1, D_CN_80319658 - lw $t2, ($t1) - beqz $t2, .L803076C0 - nop - lw $sp, 4($t1) - jalr $t2 - move $a0, $v0 - bnez $v0, .L803076C8 - nop -.L803076C0: -#else - li $t1, 2 - lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) - andi $s1, $s1, 0x2f - sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) -#endif - jal send_mesg - li $a0, 64 -.L803076C8: - beqz $s1, no_more_rcp_ints - nop -dp: - andi $t1, $s1, 0x20 - beqz $t1, no_more_rcp_ints - nop -#ifdef VERSION_CN - andi $s1, $s1, 0x1f -#endif - li $t1, MI_CLR_DP_INTR - lui $at, %hi(PHYS_TO_K1(MI_MODE_REG)) -#ifndef VERSION_CN - andi $s1, $s1, 0x1f -#endif - sw $t1, %lo(PHYS_TO_K1(MI_MODE_REG))($at) - jal send_mesg - li $a0, 72 -no_more_rcp_ints: - li $at, -1025 - b next_interrupt - and $s0, $s0, $at -glabel prenmi - lw $k1, 0x118($k0) - li $at, -4097 -#ifdef VERSION_CN - and $k1, $k1, $at - sw $k1, 0x118($k0) - la $t1, __osShutdown -#else - lui $t1, %hi(__osShutdown) - and $k1, $k1, $at - sw $k1, 0x118($k0) - addiu $t1, %lo(__osShutdown) -#endif - lw $t2, ($t1) - beqz $t2, firstnmi -#ifdef VERSION_CN - nop -#endif - li $at, -4097 - b redispatch - and $s0, $s0, $at -firstnmi: - li $t2, 1 - sw $t2, ($t1) - jal send_mesg - li $a0, 112 -#ifdef VERSION_CN - li $at, -4097 - and $s0, $s0, $at -#endif - lui $t2, %hi(__osThreadTail + 0x8) - lw $t2, %lo(__osThreadTail + 0x8)($t2) -#ifndef VERSION_CN - li $at, -4097 - and $s0, $s0, $at -#endif - lw $k1, 0x118($t2) -#ifdef VERSION_CN - li $at, -4097 -#endif - and $k1, $k1, $at - b redispatch - sw $k1, 0x118($t2) -glabel sw2 - li $at, -513 - and $t0, $t0, $at - mtc0 $t0, $13 -#ifdef VERSION_CN - li $a0, 8 - jal send_mesg - nop -#else - jal send_mesg - li $a0, 8 -#endif - li $at, -513 - b next_interrupt - and $s0, $s0, $at -glabel sw1 - li $at, -257 - and $t0, $t0, $at - mtc0 $t0, $13 -#ifdef VERSION_CN - li $a0, 0 - jal send_mesg - nop -#else - jal send_mesg - li $a0, 0 -#endif - li $at, -257 - b next_interrupt - and $s0, $s0, $at -handle_break: - li $t1, 1 - sh $t1, 0x12($k0) - jal send_mesg - li $a0, 80 - b redispatch - nop - -glabel redispatch -#ifdef VERSION_CN - lw $t1, 4($k0) - lui $t2, %hi(__osThreadTail + 0x8) - lw $t2, %lo(__osThreadTail + 0x8)($t2) - lw $t3, 4($t2) - slt $at, $t1, $t3 - beqz $at, enqueue_running - nop - move $a1, $k0 - la $a0, __osThreadTail + 0x8 - jal __osEnqueueThread - nop -#else - lui $t2, %hi(__osThreadTail + 0x8) - lw $t2, %lo(__osThreadTail + 0x8)($t2) - lw $t1, 4($k0) - lw $t3, 4($t2) - slt $at, $t1, $t3 - beqz $at, enqueue_running - nop - lui $a0, %hi(__osThreadTail + 0x8) - move $a1, $k0 - jal __osEnqueueThread - addiu $a0, %lo(__osThreadTail + 0x8) -#endif - j __osDispatchThread - nop - -enqueue_running: - la $t1, __osThreadTail + 0x8 - lw $t2, ($t1) - sw $t2, ($k0) - j __osDispatchThread - sw $k0, ($t1) - -glabel panic - lui $at, %hi(__osThreadTail + 0x14) - sw $k0, %lo(__osThreadTail + 0x14)($at) - li $t1, 1 - sh $t1, 0x10($k0) - li $t1, 2 - sh $t1, 0x12($k0) - mfc0 $t2, $8 - sw $t2, 0x124($k0) - jal send_mesg - li $a0, 96 - j __osDispatchThread - nop - -glabel send_mesg -#ifdef VERSION_CN - move $s2, $ra -#endif - la $t2, __osEventStateTab - addu $t2, $t2, $a0 - lw $t1, ($t2) -#ifndef VERSION_CN - move $s2, $ra -#endif - beqz $t1, .L80326CC4 - nop - lw $t3, 8($t1) - lw $t4, 0x10($t1) - slt $at, $t3, $t4 - beqz $at, .L80326CC4 - nop - lw $t5, 0xc($t1) - addu $t5, $t5, $t3 -#ifdef VERSION_CN - bnez $t4, .L80326C60 - div $zero, $t5, $t4 -#else - div $zero, $t5, $t4 - bnez $t4, .L80326C60 - nop -#endif - break 7 -.L80326C60: - li $at, -1 - bne $t4, $at, .L80326C78 - lui $at, 0x8000 - bne $t5, $at, .L80326C78 - nop - break 6 -.L80326C78: -#ifdef VERSION_CN - mfhi $t5 - lw $t4, 0x14($t1) - li $at, 4 - mult $t5, $at - mflo $t5 -#else - lw $t4, 0x14($t1) - mfhi $t5 - sll $t5, $t5, 2 -#endif - addu $t4, $t4, $t5 - lw $t5, 4($t2) -#ifdef VERSION_CN - sw $t5, ($t4) - addiu $t2, $t3, 1 -#else - addiu $t2, $t3, 1 - sw $t5, ($t4) -#endif - sw $t2, 8($t1) - lw $t2, ($t1) - lw $t3, ($t2) - beqz $t3, .L80326CC4 - nop - jal __osPopThread - move $a0, $t1 - move $t2, $v0 -#ifdef VERSION_CN - move $a1, $t2 - la $a0, __osThreadTail + 0x8 - jal __osEnqueueThread - nop -#else - lui $a0, %hi(__osThreadTail + 0x8) - move $a1, $t2 - jal __osEnqueueThread - addiu $a0, %lo(__osThreadTail + 0x8) -#endif -.L80326CC4: - jr $s2 - nop -handle_CpU: // coprocessor error - lui $at, 0x3000 - and $t1, $t0, $at - srl $t1, $t1, 0x1c - li $t2, 1 - bne $t1, $t2, panic - nop -#ifdef VERSION_CN - li $t1, 1 - sw $t1, 0x18($k0) - lw $k1, 0x118($k0) - lui $at, 0x2000 - or $k1, $k1, $at -#else - lw $k1, 0x118($k0) - lui $at, 0x2000 - li $t1, 1 - or $k1, $k1, $at - sw $t1, 0x18($k0) -#endif - b enqueue_running - sw $k1, 0x118($k0) - - -glabel __osEnqueueAndYield - lui $a1, %hi(__osThreadTail + 0x10) - lw $a1, %lo(__osThreadTail + 0x10)($a1) - mfc0 $t0, $12 -#ifndef VERSION_CN - lw $k1, 0x18($a1) -#endif - ori $t0, $t0, 2 - sw $t0, 0x118($a1) - sd $s0, 0x98($a1) - sd $s1, 0xa0($a1) - sd $s2, 0xa8($a1) - sd $s3, 0xb0($a1) - sd $s4, 0xb8($a1) - sd $s5, 0xc0($a1) - sd $s6, 0xc8($a1) - sd $s7, 0xd0($a1) - sd $gp, 0xe8($a1) - sd $sp, 0xf0($a1) - sd $fp, 0xf8($a1) - sd $ra, 0x100($a1) -#ifdef VERSION_CN - sw $ra, 0x11c($a1) - lw $k1, 0x18($a1) - beqz $k1, .L80326D70 - nop - cfc1 $k1, $31 - sw $k1, 0x12c($a1) -#else - beqz $k1, .L80326D70 - sw $ra, 0x11c($a1) - cfc1 $k1, $31 -#endif - sdc1 $f20, 0x180($a1) - sdc1 $f22, 0x188($a1) - sdc1 $f24, 0x190($a1) - sdc1 $f26, 0x198($a1) - sdc1 $f28, 0x1a0($a1) - sdc1 $f30, 0x1a8($a1) -#ifndef VERSION_CN - sw $k1, 0x12c($a1) -#endif - -.L80326D70: -#ifdef VERSION_EU_SH_CN - lw $k1, 0x118($a1) - andi $t1, $k1, 0xff00 - beqz $t1, .L802F3FBC - nop - la $t0, __OSGlobalIntMask - lw $t0, ($t0) - li $at, 0xFFFFFFFF - xor $t0, $t0, $at -#ifdef VERSION_CN - andi $t0, $t0, SR_IMASK - or $t1, $t1, $t0 - li $at, ~SR_IMASK -#else - lui $at, (~SR_IMASK >> 16) & 0xFFFF - andi $t0, $t0, SR_IMASK - ori $at, (~SR_IMASK & 0xFFFF) - or $t1, $t1, $t0 -#endif - and $k1, $k1, $at - or $k1, $k1, $t1 - sw $k1, 0x118($a1) -.L802F3FBC: -#endif - lui $k1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - lw $k1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($k1) -#ifdef VERSION_EU_SH_CN - beqz $k1, .L802F3FF4 - nop - la $k0, __OSGlobalIntMask - lw $k0, ($k0) -#ifdef VERSION_CN - srl $k0, $k0, 0x10 - li $at, 0xFFFFFFFF - xor $k0, $k0, $at - andi $k0, $k0, 0x3f - lw $t0, 0x128($a1) -#else - lw $t0, 0x128($a1) - li $at, 0xFFFFFFFF - srl $k0, $k0, 0x10 - xor $k0, $k0, $at - andi $k0, $k0, 0x3f -#endif - and $k0, $k0, $t0 - or $k1, $k1, $k0 -.L802F3FF4: -#endif - beqz $a0, .L80326D88 - sw $k1, 0x128($a1) - jal __osEnqueueThread - nop -.L80326D88: - j __osDispatchThread - nop - -// enqueue and pop look like compiled functions? but there's no easy way to extract them -glabel __osEnqueueThread -#ifdef VERSION_CN - move $t9, $a0 -#endif - lw $t8, ($a0) - lw $t7, 4($a1) -#ifndef VERSION_CN - move $t9, $a0 -#endif - lw $t6, 4($t8) - slt $at, $t6, $t7 - bnez $at, .L80326DC4 - nop -.L80326DAC: - move $t9, $t8 - lw $t8, ($t8) - lw $t6, 4($t8) - slt $at, $t6, $t7 - beqz $at, .L80326DAC - nop -.L80326DC4: - lw $t8, ($t9) - sw $t8, ($a1) - sw $a1, ($t9) - jr $ra - sw $a0, 8($a1) - -glabel __osPopThread - lw $v0, ($a0) - lw $t9, ($v0) - jr $ra - sw $t9, ($a0) - -#ifdef VERSION_CN -func_unused: - jr $ra - nop -#endif - -glabel __osDispatchThread -#ifdef VERSION_CN - la $a0, __osThreadTail + 0x8 - jal __osPopThread - nop -#else - lui $a0, %hi(__osThreadTail + 0x8) - jal __osPopThread - addiu $a0, %lo(__osThreadTail + 0x8) -#endif - lui $at, %hi(__osThreadTail + 0x10) - sw $v0, %lo(__osThreadTail + 0x10)($at) - li $t0, 4 - sh $t0, 0x10($v0) - move $k0, $v0 -#ifdef VERSION_EU_SH_CN -#ifdef VERSION_CN - lw $k1, 0x118($k0) - la $t0, __OSGlobalIntMask - lw $t0, ($t0) - andi $t0, $t0, SR_IMASK - andi $t1, $k1, SR_IMASK - and $t1, $t1, $t0 - li $at, ~SR_IMASK -#else - lui $t0, %hi(__OSGlobalIntMask) - lw $k1, 0x118($k0) - addiu $t0, %lo(__OSGlobalIntMask) - lw $t0, ($t0) - lui $at, (~SR_IMASK >> 16) & 0xFFFF - andi $t1, $k1, SR_IMASK - ori $at, (~SR_IMASK & 0xFFFF) - andi $t0, $t0, SR_IMASK - and $t1, $t1, $t0 -#endif - and $k1, $k1, $at - or $k1, $k1, $t1 - mtc0 $k1, $12 -#endif -.L80326E08: -#ifndef VERSION_CN - ld $k1, 0x108($k0) -#endif - ld $at, 0x20($k0) - ld $v0, 0x28($k0) -#ifndef VERSION_CN - mtlo $k1 - ld $k1, 0x110($k0) -#endif - ld $v1, 0x30($k0) - ld $a0, 0x38($k0) - ld $a1, 0x40($k0) - ld $a2, 0x48($k0) - ld $a3, 0x50($k0) - ld $t0, 0x58($k0) - ld $t1, 0x60($k0) - ld $t2, 0x68($k0) - ld $t3, 0x70($k0) - ld $t4, 0x78($k0) - ld $t5, 0x80($k0) - ld $t6, 0x88($k0) - ld $t7, 0x90($k0) - ld $s0, 0x98($k0) - ld $s1, 0xa0($k0) - ld $s2, 0xa8($k0) - ld $s3, 0xb0($k0) - ld $s4, 0xb8($k0) - ld $s5, 0xc0($k0) - ld $s6, 0xc8($k0) - ld $s7, 0xd0($k0) - ld $t8, 0xd8($k0) - ld $t9, 0xe0($k0) - ld $gp, 0xe8($k0) -#ifndef VERSION_CN - mthi $k1 -#endif - ld $sp, 0xf0($k0) - ld $fp, 0xf8($k0) - ld $ra, 0x100($k0) -#ifdef VERSION_CN - ld $k1, 0x108($k0) - mtlo $k1 - ld $k1, 0x110($k0) - mthi $k1 -#endif - lw $k1, 0x11c($k0) - mtc0 $k1, $14 -#ifndef VERSION_EU_SH_CN - lw $k1, 0x118($k0) - mtc0 $k1, $12 -#endif - lw $k1, 0x18($k0) - beqz $k1, .L80326EF0 - nop - lw $k1, 0x12c($k0) - ctc1 $k1, $31 - ldc1 $f0, 0x130($k0) - ldc1 $f2, 0x138($k0) - ldc1 $f4, 0x140($k0) - ldc1 $f6, 0x148($k0) - ldc1 $f8, 0x150($k0) - ldc1 $f10, 0x158($k0) - ldc1 $f12, 0x160($k0) - ldc1 $f14, 0x168($k0) - ldc1 $f16, 0x170($k0) - ldc1 $f18, 0x178($k0) - ldc1 $f20, 0x180($k0) - ldc1 $f22, 0x188($k0) - ldc1 $f24, 0x190($k0) - ldc1 $f26, 0x198($k0) - ldc1 $f28, 0x1a0($k0) - ldc1 $f30, 0x1a8($k0) -.L80326EF0: - lw $k1, 0x128($k0) -#ifdef VERSION_EU_SH_CN - la $k0, __OSGlobalIntMask - lw $k0, ($k0) - srl $k0, $k0, 0x10 - and $k1, $k1, $k0 -#endif - sll $k1, $k1, 1 - la $k0, __osRcpImTable - addu $k1, $k1, $k0 - lhu $k1, ($k1) -#ifdef VERSION_CN - li $k0, PHYS_TO_K1(MI_INTR_MASK_REG) -#else - // TODO: is this an la? - lui $k0, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) - addiu $k0, %lo(PHYS_TO_K1(MI_INTR_MASK_REG)) -#endif - sw $k1, ($k0) - nop - nop - nop - nop - eret -glabel __osCleanupThread - jal osDestroyThread - move $a0, $zero - -.section .data - -glabel __osHwIntTable - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 -#ifdef VERSION_CN - // CN: table is now 2 words per entry (handler, sp) - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - -// Is this part of __osHwIntTable? -glabel D_CN_80319658 - .word 0 -#endif - -#ifndef VERSION_EU_SH_CN -glabel D_80334934 - .word 0 - -glabel D_80334938 - .word 0 - .word 0 -#endif - -.section .rodata - -glabel __osIntOffTable - .byte 0x00,0x14,0x18,0x18,0x1C,0x1C,0x1C,0x1C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x04,0x08,0x08,0x0C,0x0C,0x0C,0x0C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 - -glabel __osIntTable - .word redispatch - .word sw1 - .word sw2 - .word rcp - .word cart - .word prenmi -#ifdef VERSION_EU_SH_CN - .word IP6_Hdlr - .word IP7_Hdlr -#else - .word panic - .word panic -#endif - .word counter - .word 0 - .word 0 - .word 0 diff --git a/lib/asm/__osGetCause.s b/lib/asm/__osGetCause.s deleted file mode 100644 index 770e2edb..00000000 --- a/lib/asm/__osGetCause.s +++ /dev/null @@ -1,14 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel __osGetCause - mfc0 $v0, $13 - jr $ra - nop - - nop - diff --git a/lib/asm/__osGetSR.s b/lib/asm/__osGetSR.s deleted file mode 100644 index 96d71a8a..00000000 --- a/lib/asm/__osGetSR.s +++ /dev/null @@ -1,14 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel __osGetSR - mfc0 $v0, $12 - jr $ra - nop - - nop - diff --git a/lib/asm/__osProbeTLB.s b/lib/asm/__osProbeTLB.s deleted file mode 100644 index e6369c93..00000000 --- a/lib/asm/__osProbeTLB.s +++ /dev/null @@ -1,59 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel __osProbeTLB - mfc0 $t0, $10 - andi $t1, $t0, 0xff - li $at, 0xFFFFE000 - and $t2, $a0, $at - or $t1, $t1, $t2 - mtc0 $t1, $10 - nop - nop - nop - tlbp - nop - nop - mfc0 $t3, $0 - lui $at, 0x8000 - and $t3, $t3, $at - bnez $t3, .L8032A0D8 - nop - tlbr - nop - nop - nop - mfc0 $t3, $5 - addi $t3, $t3, 0x2000 - srl $t3, $t3, 1 - and $t4, $t3, $a0 - bnez $t4, .L8032A0A8 - addi $t3, $t3, -1 - mfc0 $v0, $2 - b .L8032A0AC - nop -.L8032A0A8: - mfc0 $v0, $3 -.L8032A0AC: - andi $t5, $v0, 2 - beqz $t5, .L8032A0D8 - nop - lui $at, (0x3FFFFFC0 >> 16) // lui $at, 0x3fff - ori $at, (0x3FFFFFC0 & 0xFFFF) // ori $at, $at, 0xffc0 - and $v0, $v0, $at - sll $v0, $v0, 6 - and $t5, $a0, $t3 - add $v0, $v0, $t5 - b .L8032A0DC - nop -.L8032A0D8: - li $v0, -1 -.L8032A0DC: - mtc0 $t0, $10 - jr $ra - nop diff --git a/lib/asm/__osRestoreInt.s b/lib/asm/__osRestoreInt.s deleted file mode 100644 index 5d11c9f2..00000000 --- a/lib/asm/__osRestoreInt.s +++ /dev/null @@ -1,16 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -#include - -.section .text, "ax" - -glabel __osRestoreInt - mfc0 $t0, C0_SR - or $t0, $t0, $a0 - mtc0 $t0, C0_SR - nop - nop - jr $ra - nop diff --git a/lib/asm/__osSetCompare.s b/lib/asm/__osSetCompare.s deleted file mode 100644 index df66a566..00000000 --- a/lib/asm/__osSetCompare.s +++ /dev/null @@ -1,65 +0,0 @@ -.set noat -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -#include - - -.section .text, "ax" - -#ifdef VERSION_CN - -glabel __osSetCompare - addiu $sp, $sp, -0x38 - sd $ra, 0x30($sp) - sd $fp, 0x28($sp) - move $fp, $sp - sw $a0, 0x3c($fp) - lw $v0, 0x3c($fp) - beqz $v0, .L8030A25C - nop - jal __osDisableInt - nop - sw $v0, 0x20($fp) - lw $v0, 0x3c($fp) - lui $v1, %hi(sLastHighestCount2) # $v1, 0x8032 - lw $v1, %lo(sLastHighestCount2)($v1) - sltu $v0, $v0, $v1 - lui $v1, %hi(sNumCountOverflows2) # $v1, 0x8032 - lw $v1, %lo(sNumCountOverflows2)($v1) - addu $v0, $v0, $v1 - sw $v0, 0x24($fp) - lwu $v0, 0x24($fp) - dsll32 $v1, $v0, 0 - lwu $a0, 0x3c($fp) - or $v0, $v1, $a0 - move $a0, $v0 - dsll $v1, $a0, 1 - daddu $v1, $v1, $v0 - dsll $a0, $v1, 6 - li $at, 125 - ddivu $zero, $a0, $at - mflo $v0 - dsll32 $v0, $v0, 0 - dsra32 $v0, $v0, 0 - sw $v0, 0x3c($fp) - jal __osRestoreInt - lw $a0, 0x20($fp) -.L8030A25C: - lw $a1, 0x3c($fp) - mtc0 $a1, C0_COMPARE - move $sp, $fp - ld $ra, 0x30($sp) - ld $fp, 0x28($sp) - jr $ra - addiu $sp, $sp, 0x38 - -#else - -glabel __osSetCompare - mtc0 $a0, C0_COMPARE - jr $ra - nop - -#endif diff --git a/lib/asm/__osSetFpcCsr.s b/lib/asm/__osSetFpcCsr.s deleted file mode 100644 index c11fcd85..00000000 --- a/lib/asm/__osSetFpcCsr.s +++ /dev/null @@ -1,13 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel __osSetFpcCsr - cfc1 $v0, $31 - ctc1 $a0, $31 - jr $ra - nop - diff --git a/lib/asm/__osSetSR.s b/lib/asm/__osSetSR.s deleted file mode 100644 index fc89627f..00000000 --- a/lib/asm/__osSetSR.s +++ /dev/null @@ -1,13 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel __osSetSR - mtc0 $a0, $12 - nop - jr $ra - nop - diff --git a/lib/asm/__osSetWatchLo.s b/lib/asm/__osSetWatchLo.s deleted file mode 100644 index 48e0667d..00000000 --- a/lib/asm/__osSetWatchLo.s +++ /dev/null @@ -1,13 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel __osSetWatchLo - mtc0 $a0, $18 - nop - jr $ra - nop - diff --git a/lib/asm/__os_eu_802ef550.s b/lib/asm/__os_eu_802ef550.s deleted file mode 100644 index 15ac8f3f..00000000 --- a/lib/asm/__os_eu_802ef550.s +++ /dev/null @@ -1,21 +0,0 @@ -.set noat -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" -// cache related -glabel __os_eu_802ef550 - lui $t0,0x8000 - li $t2,0x2000 - addu $t1,$t0,$t2 - addiu $t1,$t1,-0x10 -.L: cache 0x1,0($t0) - sltu $at,$t0,$t1 - bnez $at,.L - addiu $t0,$t0,0x10 - jr $ra - nop - nop - nop diff --git a/lib/asm/bcopy.s b/lib/asm/bcopy.s deleted file mode 100644 index 859455c9..00000000 --- a/lib/asm/bcopy.s +++ /dev/null @@ -1,434 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -//TODO There seem to be patterns in these iQue diffs. Can we figure out what's causing them? Could this have been written in C? -//also ifdef hell lol - -glabel bcopy - beqz $a2, .L80323A4C - move $a3, $a1 -#ifdef VERSION_CN - beq $a0, $a1, .L80323A4C - nop - slt $at, $a1, $a0 - bnez $at, .L80323A14 - nop - add $v0, $a0, $a2 - slt $at, $a1, $v0 - beqz $at, .L80323A14 - nop - b .L80323B78 - nop -.L80323A14: - slti $at, $a2, 0x10 -#else - beq $a0, $a1, .L80323A4C - slt $at, $a1, $a0 - bnezl $at, .L80323A14 - slti $at, $a2, 0x10 - add $v0, $a0, $a2 - slt $at, $a1, $v0 - beqzl $at, .L80323A14 - slti $at, $a2, 0x10 - b .L80323B78 - slti $at, $a2, 0x10 - slti $at, $a2, 0x10 -.L80323A14: -#endif - bnez $at, .L80323A2C - nop - andi $v0, $a0, 3 - andi $v1, $a1, 3 - beq $v0, $v1, .L80323A54 - nop -.L80323A2C: - beqz $a2, .L80323A4C - nop - addu $v1, $a0, $a2 -.L80323A38: - lb $v0, ($a0) - addiu $a0, $a0, 1 -#ifdef VERSION_CN - sb $v0, ($a1) - bne $a0, $v1, .L80323A38 - addiu $a1, $a1, 1 -#else - addiu $a1, $a1, 1 - bne $a0, $v1, .L80323A38 - sb $v0, -1($a1) -#endif -.L80323A4C: - jr $ra - move $v0, $a3 - -.L80323A54: -#ifdef VERSION_CN - beqz $v0, .L80323AB8 - nop - li $at, 1 - beq $v0, $at, .L80323A9C - nop - li $at, 2 - beq $v0, $at, .L80323A88 - nop - lb $v0, ($a0) - addiu $a0, $a0, 1 - sb $v0, ($a1) - addiu $a1, $a1, 1 - b .L80323AB8 - addiu $a2, $a2, -1 -.L80323A88: - lh $v0, ($a0) -#else - beqz $v0, .L80323AB8 - li $at, 1 - beq $v0, $at, .L80323A9C - li $at, 2 - beql $v0, $at, .L80323A88 - lh $v0, ($a0) - lb $v0, ($a0) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - addiu $a2, $a2, -1 - b .L80323AB8 - sb $v0, -1($a1) - lh $v0, ($a0) -.L80323A88: -#endif - addiu $a0, $a0, 2 -#ifdef VERSION_CN - sh $v0, ($a1) - addiu $a1, $a1, 2 - b .L80323AB8 - addiu $a2, $a2, -2 -#else - addiu $a1, $a1, 2 - addiu $a2, $a2, -2 - b .L80323AB8 - sh $v0, -2($a1) -#endif -.L80323A9C: - lb $v0, ($a0) - lh $v1, 1($a0) - addiu $a0, $a0, 3 -#ifdef VERSION_CN - sb $v0, ($a1) - sh $v1, 1($a1) -#endif - addiu $a1, $a1, 3 - addiu $a2, $a2, -3 -#ifndef VERSION_CN - sb $v0, -3($a1) - sh $v1, -2($a1) -#endif -.L80323AB8: - slti $at, $a2, 0x20 -#ifdef VERSION_CN - bnez $at, .L80323B14 - nop -#else - bnezl $at, .L80323B18 - slti $at, $a2, 0x10 -#endif - lw $v0, ($a0) - lw $v1, 4($a0) - lw $t0, 8($a0) - lw $t1, 0xc($a0) - lw $t2, 0x10($a0) - lw $t3, 0x14($a0) - lw $t4, 0x18($a0) - lw $t5, 0x1c($a0) - addiu $a0, $a0, 0x20 -#ifdef VERSION_CN - sw $v0, ($a1) - sw $v1, 4($a1) - sw $t0, 8($a1) - sw $t1, 0xc($a1) - sw $t2, 0x10($a1) - sw $t3, 0x14($a1) - sw $t4, 0x18($a1) - sw $t5, 0x1c($a1) -#endif - addiu $a1, $a1, 0x20 -#ifndef VERSION_CN - addiu $a2, $a2, -0x20 - sw $v0, -0x20($a1) - sw $v1, -0x1c($a1) - sw $t0, -0x18($a1) - sw $t1, -0x14($a1) - sw $t2, -0x10($a1) - sw $t3, -0xc($a1) - sw $t4, -8($a1) -#endif - b .L80323AB8 -#ifdef VERSION_CN - addiu $a2, $a2, -0x20 -#else - sw $t5, -4($a1) -#endif -.L80323B14: - slti $at, $a2, 0x10 -.L80323B18: -#ifdef VERSION_CN - bnez $at, .L80323B50 - nop -#else - bnezl $at, .L80323B54 - slti $at, $a2, 4 -#endif - lw $v0, ($a0) - lw $v1, 4($a0) - lw $t0, 8($a0) - lw $t1, 0xc($a0) - addiu $a0, $a0, 0x10 -#ifdef VERSION_CN - sw $v0, ($a1) - sw $v1, 4($a1) - sw $t0, 8($a1) - sw $t1, 0xc($a1) -#endif - addiu $a1, $a1, 0x10 -#ifndef VERSION_CN - addiu $a2, $a2, -0x10 - sw $v0, -0x10($a1) - sw $v1, -0xc($a1) - sw $t0, -8($a1) -#endif - b .L80323B14 -#ifdef VERSION_CN - addiu $a2, $a2, -0x10 -#else - sw $t1, -4($a1) -#endif -.L80323B50: - slti $at, $a2, 4 -.L80323B54: - bnez $at, .L80323A2C - nop - lw $v0, ($a0) - addiu $a0, $a0, 4 -#ifdef VERSION_CN - sw $v0, ($a1) -#endif - addiu $a1, $a1, 4 -#ifndef VERSION_CN - addiu $a2, $a2, -4 -#endif - b .L80323B50 -#ifdef VERSION_CN - addiu $a2, $a2, -4 -#else - sw $v0, -4($a1) - slti $at, $a2, 0x10 -#endif -.L80323B78: - add $a0, $a0, $a2 -#ifdef VERSION_CN - add $a1, $a1, $a2 - slti $at, $a2, 0x10 -#endif - bnez $at, .L80323B94 -#ifdef VERSION_CN - nop -#else - add $a1, $a1, $a2 -#endif - andi $v0, $a0, 3 - andi $v1, $a1, 3 - beq $v0, $v1, .L80323BC4 - nop -.L80323B94: - beqz $a2, .L80323A4C - nop - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - subu $v1, $a0, $a2 -.L80323BA8: - lb $v0, ($a0) - addiu $a0, $a0, -1 -#ifdef VERSION_CN - sb $v0, 0($a1) -#else - addiu $a1, $a1, -1 -#endif - bne $a0, $v1, .L80323BA8 -#ifdef VERSION_CN - addiu $a1, $a1, -1 -#else - sb $v0, 1($a1) -#endif - jr $ra - move $v0, $a3 - -.L80323BC4: - beqz $v0, .L80323C28 -#ifdef VERSION_CN - nop -#endif - li $at, 3 - beq $v0, $at, .L80323C0C -#ifdef VERSION_CN - nop -#endif - li $at, 2 -#ifdef VERSION_CN - beq $v0, $at, .L80323BF4 - nop -#else - beql $v0, $at, .L80323BF8 - lh $v0, -2($a0) -#endif - lb $v0, -1($a0) - addiu $a0, $a0, -1 -#ifdef VERSION_CN - sb $v0, -1($a1) -#endif - addiu $a1, $a1, -1 -#ifndef VERSION_CN - addiu $a2, $a2, -1 -#endif - b .L80323C28 -#ifdef VERSION_CN - addiu $a2, $a2, -1 -#else - sb $v0, ($a1) -#endif -.L80323BF4: - lh $v0, -2($a0) -.L80323BF8: - addiu $a0, $a0, -2 -#ifdef VERSION_CN - sh $v0, -2($a1) -#endif - addiu $a1, $a1, -2 -#ifndef VERSION_CN - addiu $a2, $a2, -2 -#endif - b .L80323C28 -#ifdef VERSION_CN - addiu $a2, $a2, -2 -#else - sh $v0, ($a1) -#endif -.L80323C0C: - lb $v0, -1($a0) - lh $v1, -3($a0) - addiu $a0, $a0, -3 -#ifdef VERSION_CN - sb $v0, -1($a1) - sh $v1, -3($a1) - addiu $a1, $a1, -3 - addiu $a2, $a2, -3 -#else - addiu $a1, $a1, -3 - addiu $a2, $a2, -3 - sb $v0, 2($a1) - sh $v1, ($a1) -#endif -.L80323C28: - slti $at, $a2, 0x20 -#ifdef VERSION_CN - bnez $at, .L80323C84 - nop -#else - bnezl $at, .L80323C88 - slti $at, $a2, 0x10 -#endif - lw $v0, -4($a0) - lw $v1, -8($a0) - lw $t0, -0xc($a0) - lw $t1, -0x10($a0) - lw $t2, -0x14($a0) - lw $t3, -0x18($a0) - lw $t4, -0x1c($a0) - lw $t5, -0x20($a0) - addiu $a0, $a0, -0x20 -#ifdef VERSION_CN - sw $v0, -4($a1) - sw $v1, -8($a1) - sw $t0, -0xc($a1) - sw $t1, -0x10($a1) - sw $t2, -0x14($a1) - sw $t3, -0x18($a1) - sw $t4, -0x1c($a1) - sw $t5, -0x20($a1) - addiu $a1, $a1, -0x20 -#else - addiu $a1, $a1, -0x20 - addiu $a2, $a2, -0x20 - sw $v0, 0x1c($a1) - sw $v1, 0x18($a1) - sw $t0, 0x14($a1) - sw $t1, 0x10($a1) - sw $t2, 0xc($a1) - sw $t3, 8($a1) - sw $t4, 4($a1) -#endif - b .L80323C28 -#ifdef VERSION_CN - addiu $a2, $a2, -0x20 -#else - sw $t5, ($a1) -#endif -.L80323C84: - slti $at, $a2, 0x10 -.L80323C88: -#ifdef VERSION_CN - bnez $at, .L80323CC0 - nop -#else - bnezl $at, .L80323CC4 - slti $at, $a2, 4 -#endif - lw $v0, -4($a0) - lw $v1, -8($a0) - lw $t0, -0xc($a0) - lw $t1, -0x10($a0) - addiu $a0, $a0, -0x10 -#ifdef VERSION_CN - sw $v0, -4($a1) - sw $v1, -8($a1) - sw $t0, -0xc($a1) - sw $t1, -0x10($a1) - addiu $a1, $a1, -0x10 -#else - addiu $a1, $a1, -0x10 - addiu $a2, $a2, -0x10 - sw $v0, 0xc($a1) - sw $v1, 8($a1) - sw $t0, 4($a1) -#endif - b .L80323C84 -#ifdef VERSION_CN - addiu $a2, $a2, -0x10 -#else - sw $t1, ($a1) -#endif -.L80323CC0: - slti $at, $a2, 4 -.L80323CC4: - bnez $at, .L80323B94 - nop - lw $v0, -4($a0) - addiu $a0, $a0, -4 -#ifdef VERSION_CN - sw $v0, -4($a1) -#endif - addiu $a1, $a1, -4 -#ifndef VERSION_CN - addiu $a2, $a2, -4 -#endif - b .L80323CC0 -#ifdef VERSION_CN - addiu $a2, $a2, -4 -#else - sw $v0, ($a1) - nop - nop - nop -#endif diff --git a/lib/asm/bzero.s b/lib/asm/bzero.s deleted file mode 100644 index cc542f67..00000000 --- a/lib/asm/bzero.s +++ /dev/null @@ -1,102 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -// this file is probably handwritten - -//TODO There seem to be patterns in these iQue diffs. Can we figure out what's causing them? Could this have been written in C? See also bcopy.s. - -.section .text, "ax" - -glabel bzero - -#ifdef VERSION_CN - negu $v1, $a0 - blt $a1, 0xc, .L80303790 - nop - andi $v1, $v1, 3 - beqz $v1, .L80303734 - subu $a1, $a1, $v1 - swl $zero, ($a0) - addu $a0, $a0, $v1 -.L80303734: - and $a3, $a1, -32 - beqz $a3, .L80303770 - subu $a1, $a1, $a3 - addu $a3, $a3, $a0 -.L80303748: - sw $zero, ($a0) - sw $zero, 4($a0) - sw $zero, 8($a0) - sw $zero, 0xc($a0) - addiu $a0, $a0, 0x20 - sw $zero, -0x10($a0) - sw $zero, -0xc($a0) - sw $zero, -8($a0) - bne $a0, $a3, .L80303748 - sw $zero, -4($a0) -.L80303770: - and $a3, $a1, -4 - beqz $a3, .L80303790 - subu $a1, $a1, $a3 - addu $a3, $a3, $a0 -.L80303784: - addiu $a0, $a0, 4 - bne $a0, $a3, .L80303784 - sw $zero, -4($a0) -.L80303790: - blez $a1, .L803037A8 - nop - addu $a1, $a1, $a0 -.L8030379C: - addiu $a0, $a0, 1 - bne $a0, $a1, .L8030379C - sb $zero, -1($a0) -.L803037A8: - jr $ra - nop -#else - blt $a1, 0xc, .L803236BC - negu $v1, $a0 - andi $v1, $v1, 3 - beqz $v1, .L80323660 - subu $a1, $a1, $v1 - swl $zero, ($a0) - addu $a0, $a0, $v1 -.L80323660: - and $a3, $a1, -32 - beqz $a3, .L8032369C - subu $a1, $a1, $a3 - addu $a3, $a3, $a0 -.L80323674: - addiu $a0, $a0, 0x20 - sw $zero, -0x20($a0) - sw $zero, -0x1c($a0) - sw $zero, -0x18($a0) - sw $zero, -0x14($a0) - sw $zero, -0x10($a0) - sw $zero, -0xc($a0) - sw $zero, -8($a0) - bne $a0, $a3, .L80323674 - sw $zero, -4($a0) -.L8032369C: - and $a3, $a1, -4 - beqz $a3, .L803236BC - subu $a1, $a1, $a3 - addu $a3, $a3, $a0 -.L803236B0: - addiu $a0, $a0, 4 - bne $a0, $a3, .L803236B0 - sw $zero, -4($a0) -.L803236BC: - blez $a1, .L803236D4 - nop - addu $a1, $a1, $a0 -.L803236C8: - addiu $a0, $a0, 1 - bne $a0, $a1, .L803236C8 - sb $zero, -1($a0) -.L803236D4: - jr $ra -#endif - diff --git a/lib/asm/guMtxF2L.s b/lib/asm/guMtxF2L.s deleted file mode 100644 index 481213e3..00000000 --- a/lib/asm/guMtxF2L.s +++ /dev/null @@ -1,46 +0,0 @@ -.set noat -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -#ifdef VERSION_CN - -.balign 32 - -glabel guMtxF2L - li $at, 0x47800000 // 65536.000000 - mtc1 $at, $f0 - lui $t9, 0xffff - addiu $t8, $a1, 0x20 -.L80306C70: - lwc1 $f4, ($a0) - mul.s $f6, $f4, $f0 - trunc.w.s $f8, $f6 - lwc1 $f10, 4($a0) - mul.s $f16, $f10, $f0 - trunc.w.s $f18, $f16 - mfc1 $t0, $f8 - mfc1 $t1, $f18 - and $t2, $t0, $t9 - srl $t3, $t1, 0x10 - or $t4, $t2, $t3 - sw $t4, ($a1) - sll $t5, $t0, 0x10 - andi $t6, $t1, 0xffff - or $t7, $t5, $t6 - sw $t7, 0x20($a1) - addiu $a1, $a1, 4 - bne $a1, $t8, .L80306C70 - addiu $a0, $a0, 8 - jr $ra - nop - - nop - nop - nop - nop - -#endif diff --git a/lib/asm/guMtxIdentF.s b/lib/asm/guMtxIdentF.s deleted file mode 100644 index 8cbb4d49..00000000 --- a/lib/asm/guMtxIdentF.s +++ /dev/null @@ -1,32 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -#ifdef VERSION_CN - -.balign 32 - -glabel guMtxIdentF - lui $t0, 0x3f80 - sw $t0, ($a0) - sw $zero, 4($a0) - sw $zero, 8($a0) - sw $zero, 0xc($a0) - sw $zero, 0x10($a0) - sw $t0, 0x14($a0) - sw $zero, 0x18($a0) - sw $zero, 0x1c($a0) - sw $zero, 0x20($a0) - sw $zero, 0x24($a0) - sw $t0, 0x28($a0) - sw $zero, 0x2c($a0) - sw $zero, 0x30($a0) - sw $zero, 0x34($a0) - sw $zero, 0x38($a0) - jr $ra - sw $t0, 0x3c($a0) - -#endif diff --git a/lib/asm/guNormalize.s b/lib/asm/guNormalize.s deleted file mode 100644 index a02ad034..00000000 --- a/lib/asm/guNormalize.s +++ /dev/null @@ -1,33 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -#ifdef VERSION_CN - -glabel guNormalize - lwc1 $f4, ($a0) - lwc1 $f6, ($a1) - lwc1 $f8, ($a2) - mul.s $f10, $f4, $f4 - li $t0, 0x3F800000 # 1.000000 - mul.s $f16, $f6, $f6 - add.s $f18, $f10, $f16 - mul.s $f16, $f8, $f8 - add.s $f10, $f16, $f18 - mtc1 $t0, $f18 - sqrt.s $f16, $f10 - div.s $f10, $f18, $f16 - mul.s $f16, $f4, $f10 - nop - mul.s $f18, $f6, $f10 - nop - mul.s $f4, $f8, $f10 - swc1 $f16, ($a0) - swc1 $f18, ($a1) - jr $ra - swc1 $f4, ($a2) - -#endif diff --git a/lib/asm/guScale.s b/lib/asm/guScale.s deleted file mode 100644 index c315e4c7..00000000 --- a/lib/asm/guScale.s +++ /dev/null @@ -1,55 +0,0 @@ -.set noat -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -#ifdef VERSION_CN - -.balign 32 - -glabel guScale - li $at, 0x47800000 // 65536.000000 - mtc1 $at, $f4 - mtc1 $a1, $f6 - mul.s $f8, $f6, $f4 - trunc.w.s $f10, $f8 - mfc1 $t1, $f10 - srl $t2, $t1, 0x10 - sll $t0, $t2, 0x10 - sw $t0, ($a0) - sll $t2, $t1, 0x10 - sw $t2, 0x20($a0) - mtc1 $a2, $f6 - mul.s $f8, $f6, $f4 - trunc.w.s $f10, $f8 - mfc1 $t1, $f10 - srl $t0, $t1, 0x10 - sw $t0, 8($a0) - andi $t2, $t1, 0xffff - sw $t2, 0x28($a0) - mtc1 $a3, $f6 - mul.s $f8, $f6, $f4 - trunc.w.s $f10, $f8 - mfc1 $t1, $f10 - srl $t2, $t1, 0x10 - sll $t0, $t2, 0x10 - sw $t0, 0x14($a0) - sll $t2, $t1, 0x10 - sw $t2, 0x34($a0) - li $t0, 1 - sw $t0, 0x1c($a0) - sw $zero, 4($a0) - sw $zero, 0xc($a0) - sw $zero, 0x10($a0) - sw $zero, 0x18($a0) - sw $zero, 0x24($a0) - sw $zero, 0x2c($a0) - sw $zero, 0x30($a0) - sw $zero, 0x38($a0) - jr $ra - sw $zero, 0x3c($a0) - -#endif diff --git a/lib/asm/guTranslate.s b/lib/asm/guTranslate.s deleted file mode 100644 index c0e02559..00000000 --- a/lib/asm/guTranslate.s +++ /dev/null @@ -1,65 +0,0 @@ -.set noat -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -#ifdef VERSION_CN - -.balign 16 - -glabel guTranslate - li $at, 0x47800000 // 65536.000000 - mtc1 $at, $f4 - mtc1 $a1, $f6 - mul.s $f8, $f6, $f4 - trunc.w.s $f10, $f8 - mfc1 $t1, $f10 - mtc1 $a2, $f6 - mul.s $f8, $f6, $f4 - trunc.w.s $f10, $f8 - mfc1 $t3, $f10 - srl $t2, $t1, 0x10 - sll $t0, $t2, 0x10 - srl $t2, $t3, 0x10 - or $t0, $t0, $t2 - sw $t0, 0x18($a0) - sll $t0, $t1, 0x10 - sll $t2, $t3, 0x10 - srl $t2, $t2, 0x10 - or $t0, $t0, $t2 - sw $t0, 0x38($a0) - mtc1 $a3, $f6 - mul.s $f8, $f6, $f4 - trunc.w.s $f10, $f8 - mfc1 $t1, $f10 - srl $t2, $t1, 0x10 - sll $t0, $t2, 0x10 - addiu $t0, $t0, 1 - sw $t0, 0x1c($a0) - sll $t2, $t1, 0x10 - sw $t2, 0x3c($a0) - sw $zero, ($a0) - sw $zero, 4($a0) - sw $zero, 8($a0) - sw $zero, 0xc($a0) - sw $zero, 0x10($a0) - sw $zero, 0x14($a0) - sw $zero, 0x20($a0) - sw $zero, 0x24($a0) - sw $zero, 0x28($a0) - sw $zero, 0x2c($a0) - sw $zero, 0x30($a0) - sw $zero, 0x34($a0) - lui $t0, 1 - ori $t0, $t0, 0 - sw $t0, ($a0) - sw $t0, 0x14($a0) - lui $t0, (0x00000001 >> 16) # lui $t0, 0 - ori $t0, (0x00000001 & 0xFFFF) # ori $t0, $t0, 1 - jr $ra - sw $t0, 8($a0) - -#endif diff --git a/lib/asm/iQueKernelCalls.s b/lib/asm/iQueKernelCalls.s deleted file mode 100644 index 9dcde049..00000000 --- a/lib/asm/iQueKernelCalls.s +++ /dev/null @@ -1,42 +0,0 @@ -.set noat -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -.macro def label, num - glabel \label - li $v0, \num - lui $t0, (0xA4300014 >> 16) - ori $t0, (0xA4300014 & 0xFFFF) - lw $t1, ($t0) // traps the iQue OS and performs the function - nop - jr $ra - nop -.endm - - -.section .text, "ax" - -def skGetId, 0x0 -def skLaunchSetup, 0x1 -def skLaunch, 0x2 -def skRecryptListValid, 0x3 -def skRecryptBegin, 0x4 -def skRecryptData, 0x5 -def skRecryptComputeState, 0x6 -def skRecryptEnd, 0x7 -def skSignHash, 0x8 -def skVerifyHash, 0x9 -def skGetConsumption, 0xa -def skAdvanceTicketWindow, 0xb -def skSetLimit, 0xc -def skExit, 0xd -def skKeepAlive, 0xe - -// developer calls -def sk0f, 0x0f -def sk10, 0x10 -def sk11, 0x11 -def sk12, 0x12 -def sk13, 0x13 -def sk14, 0x14 diff --git a/lib/asm/llmuldiv_gcc.s b/lib/asm/llmuldiv_gcc.s deleted file mode 100644 index 9ef338ee..00000000 --- a/lib/asm/llmuldiv_gcc.s +++ /dev/null @@ -1,103 +0,0 @@ -// assembler directives -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -#ifndef VERSION_CN - - -.section .text, "ax" - -/* -------------------------------------------------------------------------------------- */ -/* need to asm these functions because lib32gcc-7-dev-mips-cross does not exist so we */ -/* cannot naturally link a libgcc variant for this target given this architecture and */ -/* compiler. Until we have a good workaround with a gcc target that doesn't involve */ -/* assuming a 32-bit to 64-bit change, we have to encode these functions as raw assembly */ -/* for it to compile. */ -/* -------------------------------------------------------------------------------------- */ - -/* TODO: Is there a non-insane way to fix this hack that doesn't involve the user compiling */ -/* a library themselves? */ -glabel __umoddi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddivu $zero, $t6, $t7 - bnez $t7, .L80324144 - nop - break 7 -.L80324144: - mfhi $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -glabel __udivdi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddivu $zero, $t6, $t7 - bnez $t7, .L80324180 - nop - break 7 -.L80324180: - mflo $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -glabel __moddi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddivu $zero, $t6, $t7 - bnez $t7, .L803241E8 - nop - break 7 -.L803241E8: - mfhi $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -glabel __divdi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddiv $zero, $t6, $t7 - nop - bnez $t7, .L80324228 - nop - break 7 -.L80324228: - daddiu $at, $zero, -1 - bne $t7, $at, .L80324244 - daddiu $at, $zero, 1 - dsll32 $at, $at, 0x1f - bne $t6, $at, .L80324244 - nop - break 6 -.L80324244: - mflo $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -#endif diff --git a/lib/asm/osGetCount.s b/lib/asm/osGetCount.s deleted file mode 100644 index aa4f3316..00000000 --- a/lib/asm/osGetCount.s +++ /dev/null @@ -1,83 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -.section .text, "ax" - -#ifdef VERSION_CN - -glabel osGetCount - addiu $sp, $sp, -0x38 - sd $ra, 0x30($sp) - sd $fp, 0x28($sp) - jal __osDisableInt - move $fp, $sp - sw $v0, 0x24($fp) - mfc0 $a1, $9 - sw $a1, 0x20($fp) - lw $v0, 0x20($fp) - lui $v1, %hi(sLastHighestCount) # $v1, 0x8032 - lw $v1, %lo(sLastHighestCount)($v1) - sltu $v0, $v0, $v1 - beqz $v0, .L80304FCC - nop - lui $v0, %hi(sNumCountOverflows) # $v0, 0x8032 - lw $v0, %lo(sNumCountOverflows)($v0) - addiu $v1, $v0, 1 - sw $v1, sNumCountOverflows -.L80304FCC: - lw $v0, 0x20($fp) - sw $v0, sLastHighestCount - lui $v0, %hi(sNumCountOverflows) // $v0, 0x8032 - lwu $v0, %lo(sNumCountOverflows)($v0) - dsll32 $v1, $v0, 0 - lwu $a0, 0x20($fp) - or $v0, $v1, $a0 - move $a0, $v0 - dsll $v1, $a0, 5 - dsubu $v1, $v1, $v0 - dsll $a0, $v1, 2 - daddu $a0, $a0, $v0 -.set noat // gas seems to add an extra mflo $zero after, if we don't manually use $at - li $at, 192 - ddivu $zero, $a0, $at -.set at - mflo $v0 - dsll32 $v0, $v0, 0 - dsra32 $v0, $v0, 0 - sw $v0, 0x20($fp) - lw $v0, 0x20($fp) - lui $v1, %hi(sLastHighestCount2) // $v1, 0x8032 - lw $v1, %lo(sLastHighestCount2)($v1) - sltu $v0, $v0, $v1 - beqz $v0, .L80305044 - nop - lui $v0, %hi(sNumCountOverflows2) // $v0, 0x8032 - lw $v0, %lo(sNumCountOverflows2)($v0) - addiu $v1, $v0, 1 - sw $v1, sNumCountOverflows2 -.L80305044: - lw $v0, 0x20($fp) - sw $v0, sLastHighestCount2 - jal __osRestoreInt - lw $a0, 0x24($fp) - lw $v1, 0x20($fp) - j .L80305064 - move $v0, $v1 -.L80305064: - move $sp, $fp - ld $ra, 0x30($sp) - ld $fp, 0x28($sp) - jr $ra - addiu $sp, $sp, 0x38 - -#else - -glabel osGetCount - mfc0 $v0, $9 - jr $ra - nop - - nop - -#endif diff --git a/lib/asm/osInvalDCache.s b/lib/asm/osInvalDCache.s deleted file mode 100644 index 54bba4e8..00000000 --- a/lib/asm/osInvalDCache.s +++ /dev/null @@ -1,65 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel osInvalDCache - blez $a1, .L80323500 - nop - li $t3, 8192 - sltu $at, $a1, $t3 - beqz $at, .L80323508 - nop - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, .L80323500 - nop -#ifdef VERSION_CN - addiu $t1, $t1, -0x10 - andi $t2, $t0, 0xf - beqz $t2, .L803234D0 - nop -#else - andi $t2, $t0, 0xf - beqz $t2, .L803234D0 - addiu $t1, $t1, -0x10 -#endif - subu $t0, $t0, $t2 - cache 0x15, ($t0) - sltu $at, $t0, $t1 - beqz $at, .L80323500 - nop - addiu $t0, $t0, 0x10 -.L803234D0: - andi $t2, $t1, 0xf - beqz $t2, .L803234F0 - nop - subu $t1, $t1, $t2 - cache 0x15, 0x10($t1) - sltu $at, $t1, $t0 - bnez $at, .L80323500 - nop -.L803234F0: - cache 0x11, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L803234F0 - addiu $t0, $t0, 0x10 -.L80323500: - jr $ra - nop - -.L80323508: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -0x10 -.L80323514: - cache 1, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L80323514 - addiu $t0, $t0, 0x10 - jr $ra - nop diff --git a/lib/asm/osInvalICache.s b/lib/asm/osInvalICache.s deleted file mode 100644 index 1d92d4df..00000000 --- a/lib/asm/osInvalICache.s +++ /dev/null @@ -1,48 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel osInvalICache - blez $a1, .L80323728 - nop - li $t3, 16384 - sltu $at, $a1, $t3 - beqz $at, .L80323730 - nop - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, .L80323728 - nop -#ifdef VERSION_CN - addiu $t1, $t1, -0x20 - andi $t2, $t0, 0x1f -#else - andi $t2, $t0, 0x1f - addiu $t1, $t1, -0x20 -#endif - subu $t0, $t0, $t2 -.L80323718: - cache 0x10, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L80323718 - addiu $t0, $t0, 0x20 -.L80323728: - jr $ra - nop - -.L80323730: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -0x20 -.L8032373C: - cache 0, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L8032373C - addiu $t0, $t0, 0x20 - jr $ra - nop diff --git a/lib/asm/osMapTLB.s b/lib/asm/osMapTLB.s deleted file mode 100644 index 891e4f11..00000000 --- a/lib/asm/osMapTLB.s +++ /dev/null @@ -1,62 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -// This file is handwritten - -// void osMapTLB(s32 index, OSPageMask pm, void *vaddr, u32 evenpaddr, u32 oddpaddr, s32 asid); -glabel osMapTLB - mfc0 $t0, $10 - mtc0 $a0, $0 - mtc0 $a1, $5 - lw $t1, 0x14($sp) #asid - beq $t1, -1, .L803214D8 - li $t4, 1 - li $t2, 30 - b .L803214DC - or $a2, $a2, $t1 #vaddr -.L803214D8: - li $t2, 31 -.L803214DC: - mtc0 $a2, $10 #vaddr - beq $a3, -1, .L80321500 #even paddr - nop - srl $t3, $a3, 6 #evenpaddr - or $t3, $t3, $t2 - mtc0 $t3, $2 - b .L80321504 - nop -.L80321500: - mtc0 $t4, $2 -.L80321504: - lw $t3, 0x10($sp) #oddpaddr - beq $t3, -1, .L80321528 - nop - srl $t3, $t3, 6 - or $t3, $t3, $t2 - mtc0 $t3, $3 - b .L80321540 - nop -.L80321528: - mtc0 $t4, $3 - bne $a3, -1, .L80321540 #evenpaddr - nop - lui $t3, 0x8000 - mtc0 $t3, $10 -.L80321540: - nop - tlbwi - nop - nop - nop - nop - mtc0 $t0, $10 - jr $ra - nop #file gets padded but - nop - nop - nop - diff --git a/lib/asm/osMapTLBRdb.s b/lib/asm/osMapTLBRdb.s deleted file mode 100644 index 04c13e2a..00000000 --- a/lib/asm/osMapTLBRdb.s +++ /dev/null @@ -1,35 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel osMapTLBRdb - mfc0 $t0, $10 - li $t1, 31 - mtc0 $t1, $0 - mtc0 $zero, $5 - li $t2, 23 - lui $t1, 0xc000 - mtc0 $t1, $10 - lui $t1, 0x8000 - srl $t3, $t1, 6 - or $t3, $t3, $t2 - mtc0 $t3, $2 - li $t1, 1 - mtc0 $t1, $3 - nop - tlbwi - nop - nop - nop - nop - mtc0 $t0, $10 - jr $ra - nop - - nop - nop - diff --git a/lib/asm/osSetIntMask.s b/lib/asm/osSetIntMask.s deleted file mode 100644 index d5d70da6..00000000 --- a/lib/asm/osSetIntMask.s +++ /dev/null @@ -1,139 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -#include -#include -#include - -.section .text, "ax" - -glabel osSetIntMask -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - mfc0 $t4, $12 - andi $v0, $t4, OS_IM_CPU - lui $t0, %hi(__OSGlobalIntMask) // $t0, 0x8030 - addiu $t0, %lo(__OSGlobalIntMask) // addiu $t0, $t0, 0x208c - lw $t3, ($t0) - li $at, 0xFFFFFFFF - xor $t0, $t3, $at - andi $t0, $t0, SR_IMASK - or $v0, $v0, $t0 -#else - mfc0 $t1, $12 - andi $v0, $t1, OS_IM_CPU -#endif - lui $t2, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) // $t2, 0xa430 - lw $t2, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t2) -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - beqz $t2, .L80200074 - srl $t1, $t3, 0x10 - li $at, 0xFFFFFFFF - xor $t1, $t1, $at - andi $t1, $t1, 0x3f - or $t2, $t2, $t1 -.L80200074: -#endif - sll $t2, $t2, 0x10 - or $v0, $v0, $t2 - lui $at, 0x3f - and $t0, $a0, $at -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - and $t0, $t0, $t3 -#endif - srl $t0, $t0, 0xf - lui $t2, %hi(__osRcpImTable) - addu $t2, $t2, $t0 - lhu $t2, %lo(__osRcpImTable)($t2) - lui $at, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) // $at, 0xa430 - sw $t2, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($at) - andi $t0, $a0, OS_IM_CPU -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - andi $t1, $t3, 0xff00 - and $t0, $t0, $t1 -#endif - lui $at, (0xFFFF00FF >> 16) // lui $at, 0xffff - ori $at, (0xFFFF00FF & 0xFFFF) // ori $at, $at, 0xff -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - and $t4, $t4, $at - or $t4, $t4, $t0 - mtc0 $t4, $12 -#else - and $t1, $t1, $at - or $t1, $t1, $t0 - mtc0 $t1, $12 -#endif - nop - nop - jr $ra - nop - - -.section .rodata - -glabel __osRcpImTable -.half 0x0555 -.half 0x0556 -.half 0x0559 -.half 0x055A -.half 0x0565 -.half 0x0566 -.half 0x0569 -.half 0x056A -.half 0x0595 -.half 0x0596 -.half 0x0599 -.half 0x059A -.half 0x05A5 -.half 0x05A6 -.half 0x05A9 -.half 0x05AA -.half 0x0655 -.half 0x0656 -.half 0x0659 -.half 0x065A -.half 0x0665 -.half 0x0666 -.half 0x0669 -.half 0x066A -.half 0x0695 -.half 0x0696 -.half 0x0699 -.half 0x069A -.half 0x06A5 -.half 0x06A6 -.half 0x06A9 -.half 0x06AA -.half 0x0955 -.half 0x0956 -.half 0x0959 -.half 0x095A -.half 0x0965 -.half 0x0966 -.half 0x0969 -.half 0x096A -.half 0x0995 -.half 0x0996 -.half 0x0999 -.half 0x099A -.half 0x09A5 -.half 0x09A6 -.half 0x09A9 -.half 0x09AA -.half 0x0A55 -.half 0x0A56 -.half 0x0A59 -.half 0x0A5A -.half 0x0A65 -.half 0x0A66 -.half 0x0A69 -.half 0x0A6A -.half 0x0A95 -.half 0x0A96 -.half 0x0A99 -.half 0x0A9A -.half 0x0AA5 -.half 0x0AA6 -.half 0x0AA9 -.half 0x0AAA diff --git a/lib/asm/osUnmapTLBAll.s b/lib/asm/osUnmapTLBAll.s deleted file mode 100644 index ff692c3f..00000000 --- a/lib/asm/osUnmapTLBAll.s +++ /dev/null @@ -1,34 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel osUnmapTLBAll - mfc0 $t0, $10 -#ifdef VERSION_CN - li $t1, 30 -#else - li $t1, 31 -#endif - lui $t2, 0x8000 - mtc0 $t2, $10 - mtc0 $zero, $2 - mtc0 $zero, $3 -.L80321588: - mtc0 $t1, $0 - nop - tlbwi - nop - nop - addi $t1, $t1, -1 -#ifdef VERSION_CN - bgez $t1, .L80321588 -#else - bnezl $t1, .L80321588 #bnezl, bnez but with likely hint -#endif - nop - mtc0 $t0, $10 - jr $ra - nop diff --git a/lib/asm/osWritebackDCache.s b/lib/asm/osWritebackDCache.s deleted file mode 100644 index 3d506ecb..00000000 --- a/lib/asm/osWritebackDCache.s +++ /dev/null @@ -1,43 +0,0 @@ -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel osWritebackDCache - blez $a1, .osWritebackDCacheReturn - nop - li $t3, 8192 - bgeu $a1, $t3, .L80324E40 - nop - move $t0, $a0 - addu $t1, $a0, $a1 - bgeu $t0, $t1, .osWritebackDCacheReturn - nop -#ifdef VERSION_CN - addiu $t1, $t1, -0x10 - andi $t2, $t0, 0xf -#else - andi $t2, $t0, 0xf - addiu $t1, $t1, -0x10 -#endif - subu $t0, $t0, $t2 -.L80324E28: - cache 0x19, ($t0) - bltu $t0, $t1, .L80324E28 - addiu $t0, $t0, 0x10 -.osWritebackDCacheReturn: - jr $ra - nop - -.L80324E40: - lui $t0, 0x8000 - addu $t1, $t0, $t3 - addiu $t1, $t1, -0x10 -.L80324E4C: - cache 1, ($t0) - bltu $t0, $t1, .L80324E4C - addiu $t0, 0x10 // addiu $t0, $t0, 0x10 - jr $ra - nop diff --git a/lib/asm/osWritebackDCacheAll.s b/lib/asm/osWritebackDCacheAll.s deleted file mode 100644 index d194e8f7..00000000 --- a/lib/asm/osWritebackDCacheAll.s +++ /dev/null @@ -1,23 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - - -.section .text, "ax" - -glabel osWritebackDCacheAll - li $t0, K0BASE - li $t2, 8192 - addu $t1, $t0, $t2 - addiu $t1, $t1, -0x10 -.L80322020: - cache 1, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L80322020 - addiu $t0, $t0, 0x10 - jr $ra - nop - - nop - nop diff --git a/lib/asm/parameters.s b/lib/asm/parameters.s deleted file mode 100644 index 0921794c..00000000 --- a/lib/asm/parameters.s +++ /dev/null @@ -1,34 +0,0 @@ -.macro gsymbol sym addr -.global \sym -.equ \sym, \addr -#ifndef VERSION_JP -nop -nop -#endif -.endm - -.text -gsymbol osTvType 0x80000300 -gsymbol osRomType 0x80000304 -gsymbol osRomBase 0x80000308 -gsymbol osResetType 0x8000030C -gsymbol osCiCId 0x80000310 -gsymbol osVersion 0x80000314 -gsymbol osMemSize 0x80000318 -gsymbol osAppNmiBuffer 0x8000031C -#if defined(VERSION_SH) || defined(VERSION_CN) -nop -nop -nop -nop -nop -nop -nop -nop -#ifdef VERSION_CN -nop -nop -nop -nop -#endif -#endif diff --git a/lib/asm/sqrtf.s b/lib/asm/sqrtf.s deleted file mode 100644 index 91cd3eb5..00000000 --- a/lib/asm/sqrtf.s +++ /dev/null @@ -1,10 +0,0 @@ -.set noat // allow manual use of $at -.set noreorder // don't insert nops after branches - -#include "macros.inc" - -.section .text, "ax" - -glabel sqrtf - jr $ra - sqrt.s $f0, $f12 diff --git a/lib/src/NaN.c b/lib/src/NaN.c deleted file mode 100644 index 05f4031c..00000000 --- a/lib/src/NaN.c +++ /dev/null @@ -1,5 +0,0 @@ -typedef union { - int i; - float f; -} fu; -const fu NAN = { 0x7f810000 }; diff --git a/lib/src/_Ldtob.c b/lib/src/_Ldtob.c deleted file mode 100644 index ab1067ad..00000000 --- a/lib/src/_Ldtob.c +++ /dev/null @@ -1,278 +0,0 @@ -#include "libultra_internal.h" -#include -#include -#include -#include "printf.h" - -#define BUFF_LEN 0x20 - -static s16 _Ldunscale(s16 *, printf_struct *); -static void _Genld(printf_struct *, fmt_type, fmt_type *, s16, s16); - -const double pows[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L }; - -/* float properties */ -#define _D0 0 -#define _DBIAS 0x3ff -#define _DLONG 1 -#define _DOFF 4 -#define _FBIAS 0x7e -#define _FOFF 7 -#define _FRND 1 -#define _LBIAS 0x3ffe -#define _LOFF 15 -/* integer properties */ -#define _C2 1 -#define _CSIGN 1 -#define _ILONG 0 -#define _MBMAX 8 -#define NAN 2 -#define INF 1 -#define FINITE -1 -#define _DFRAC ((1 << _DOFF) - 1) -#define _DMASK (0x7fff & ~_DFRAC) -#define _DMAX ((1 << (15 - _DOFF)) - 1) -#define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1)) -#define _DSIGN 0x8000 -#if _D0 == 3 -#define _D1 2 /* little-endian order */ -#define _D2 1 -#define _D3 0 -#else -#define _D1 1 /* big-endian order */ -#define _D2 2 -#define _D3 3 -#endif - -void _Ldtob(printf_struct *args, fmt_type type) { - fmt_type buff[BUFF_LEN]; - fmt_type *ptr; - f64 val; - /* maybe struct? */ - s16 err; - s16 nsig; - s16 exp; - - s32 i; - s32 n; - f64 factor; - s32 gen; - s32 j; - - ptr = buff; - val = args->value.f64; - if (args->precision < 0) { - args->precision = 6; - } else { - if (args->precision == 0 && (type == 'g' || type == 'G')) { - args->precision = 1; - } - } - err = _Ldunscale(&exp, args); - if (err > 0) { - memcpy(args->buff, err == 2 ? "NaN" : "Inf", args->part2_len = 3); - return; - } - if (err == 0) { - nsig = 0; - exp = 0; - } else { - if (val < 0) { - val = -val; - } - exp = exp * 30103 / 0x000186A0 - 4; - if (exp < 0) { - n = (-exp + 3) & ~3; - exp = -n; - for (i = 0; n > 0; n >>= 1, i++) { - if ((n & 1) != 0) { - val *= pows[i]; - } - } - } else { - if (exp > 0) { - factor = 1; - exp &= ~3; - for (n = exp, i = 0; n > 0; n >>= 1, i++) { - if ((n & 1) != 0) { - factor *= pows[i]; - } - } - val /= factor; - } - } - gen = args->precision + ((type == 'f') ? exp + 10 : 6); - if (gen > 0x13) { - gen = 0x13; - } - *ptr++ = '0'; - while (gen > 0 && 0 < val) { - s32 lo = val; - if ((gen -= 8) > 0) { - val = (val - lo) * 1.0e8; - } - ptr = ptr + 8; - for (j = 8; lo > 0 && --j >= 0;) { - ldiv_t qr = ldiv(lo, 10); - *--ptr = qr.rem + '0'; - lo = qr.quot; - } - while (--j >= 0) { - ptr--; - *ptr = '0'; - } - ptr += 8; - } - - gen = ptr - &buff[1]; - for (ptr = &buff[1], exp += 7; *ptr == '0'; ptr++) { - --gen, --exp; - } - - nsig = args->precision + ((type == 'f') ? exp + 1 : ((type == 'e' || type == 'E') ? 1 : 0)); - if (gen < nsig) { - nsig = gen; - } - if (nsig > 0) { - fmt_type drop = (nsig < gen && ptr[nsig] > '4') ? '9' : '0'; - s32 n2; - - for (n2 = nsig; ptr[--n2] == drop;) { - nsig--; - } - if (drop == '9') { - ptr[n2]++; - } - if (n2 < 0) { - --ptr, ++nsig, ++exp; - } - } - } - _Genld(args, type, ptr, nsig, exp); -} - -static s16 _Ldunscale(s16 *pex, printf_struct *px) { - - unsigned short *ps = (unsigned short *) px; - short xchar = (ps[_D0] & _DMASK) >> _DOFF; - if (xchar == _DMAX) { /* NaN or INF */ - *pex = 0; - return (s16)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF); - } else if (0 < xchar) { - ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF); - *pex = xchar - (_DBIAS - 1); - return (FINITE); - } - if (0 > xchar) { - return NAN; - } else { - *pex = 0; - return (0); - } -} - -static void _Genld(printf_struct *px, fmt_type code, fmt_type *p, s16 nsig, s16 xexp) { - const fmt_type point = '.'; - if (nsig <= 0) { - nsig = 1, - - p = (fmt_type *) "0"; - } - - if (code == 'f' - || ((code == 'g' || code == 'G') && (-4 <= xexp) && (xexp < px->precision))) { /* 'f' format */ - ++xexp; /* change to leading digit count */ - if (code != 'f') { /* fixup for 'g' */ - if (!(px->flags & FLAGS_HASH) && nsig < px->precision) { - px->precision = nsig; - } - if ((px->precision -= xexp) < 0) { - px->precision = 0; - } - } - if (xexp <= 0) { /* digits only to right of point */ - px->buff[px->part2_len++] = '0'; - if (0 < px->precision || px->flags & FLAGS_HASH) { - px->buff[px->part2_len++] = point; - } - if (px->precision < -xexp) { - xexp = -px->precision; - } - px->num_mid_zeros = -xexp; - px->precision += xexp; - if (px->precision < nsig) { - nsig = px->precision; - } - memcpy(&px->buff[px->part2_len], p, px->part3_len = nsig); - px->num_trailing_zeros = px->precision - nsig; - } else if (nsig < xexp) { /* zeros before point */ - memcpy(&px->buff[px->part2_len], p, nsig); - px->part2_len += nsig; - px->num_mid_zeros = xexp - nsig; - if (0 < px->precision || px->flags & FLAGS_HASH) { - px->buff[px->part2_len] = point, ++px->part3_len; - } - px->num_trailing_zeros = px->precision; - } else { /* enough digits before point */ - memcpy(&px->buff[px->part2_len], p, xexp); - px->part2_len += xexp; - nsig -= xexp; - if (0 < px->precision || px->flags & FLAGS_HASH) { - px->buff[px->part2_len++] = point; - } - if (px->precision < nsig) { - nsig = px->precision; - } - memcpy(&px->buff[px->part2_len], p + xexp, nsig); - px->part2_len += nsig; - px->num_mid_zeros = px->precision - nsig; - } - } else { /* 'e' format */ - if (code == 'g' || code == 'G') { /* fixup for 'g' */ - if (nsig < px->precision) { - px->precision = nsig; - } - if (--px->precision < 0) { - px->precision = 0; - } - code = code == 'g' ? 'e' : 'E'; - } - px->buff[px->part2_len++] = *p++; - if (0 < px->precision || px->flags & FLAGS_HASH) { - px->buff[px->part2_len++] = point; - } - if (0 < px->precision) { /* put fraction digits */ - if (px->precision < --nsig) { - nsig = px->precision; - } - memcpy(&px->buff[px->part2_len], p, nsig); - px->part2_len += nsig; - px->num_mid_zeros = px->precision - nsig; - } - p = (fmt_type *) &px->buff[px->part2_len]; /* put exponent */ - *p++ = code; - if (0 <= xexp) { - *p++ = '+'; - } else { /* negative exponent */ - *p++ = '-'; - xexp = -xexp; - } - if (100 <= xexp) { /* put oversize exponent */ - if (1000 <= xexp) { - *p++ = xexp / 1000 + '0', xexp %= 1000; - } - *p++ = xexp / 100 + '0', xexp %= 100; - } - *p++ = xexp / 10 + '0', xexp %= 10; - *p++ = xexp + '0'; - px->part3_len = p - (fmt_type *) &px->buff[px->part2_len]; - } - if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */ - int n = - px->part1_len + px->part2_len + px->num_mid_zeros + px->part3_len + px->num_trailing_zeros; - - if (n < px->width) { - px->num_leading_zeros = px->width - n; - } - } -} diff --git a/lib/src/_Litob.c b/lib/src/_Litob.c deleted file mode 100644 index c1fbabd5..00000000 --- a/lib/src/_Litob.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "libultra_internal.h" -#include -#include -#include "printf.h" - -#define BUFF_LEN 0x18 - -static u8 ldigs[] = "0123456789abcdef"; -static u8 udigs[] = "0123456789ABCDEF"; - -void _Litob(printf_struct *args, fmt_type type) { - u8 buff[BUFF_LEN]; - const u8 *num_map; - s32 base; - s32 buff_ind; - u64 num; - lldiv_t quotrem; - - if (type == 'X') { - num_map = udigs; - } else { - num_map = ldigs; - } - - base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); - buff_ind = BUFF_LEN; - num = args->value.s64; - - if ((type == 'd' || type == 'i') && args->value.s64 < 0) { - num = -num; - } - - if (num != 0 || args->precision != 0) { - buff[--buff_ind] = num_map[num % base]; - } - - args->value.s64 = num / base; - - while (args->value.s64 > 0 && buff_ind > 0) { - quotrem = lldiv(args->value.s64, base); - args->value.s64 = quotrem.quot; - buff[--buff_ind] = num_map[quotrem.rem]; - } - - args->part2_len = BUFF_LEN - buff_ind; - - memcpy(args->buff, buff + buff_ind, args->part2_len); - - if (args->part2_len < args->precision) { - args->num_leading_zeros = args->precision - args->part2_len; - } - - if (args->precision < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { - buff_ind = args->width - args->part1_len - args->num_leading_zeros - args->part2_len; - if (buff_ind > 0) { - args->num_leading_zeros += buff_ind; - } - } -} diff --git a/lib/src/_Printf.c b/lib/src/_Printf.c deleted file mode 100644 index 5252a207..00000000 --- a/lib/src/_Printf.c +++ /dev/null @@ -1,232 +0,0 @@ -#include "libultra_internal.h" -#include -#include -#include "printf.h" - -#define ATOI(i, a) \ - for (i = 0; *a >= '0' && *a <= '9'; a++) \ - if (i < 999) \ - i = i * 10 + *a - '0'; -#define _PROUT(dst, fmt, _size) \ - if (_size > 0) { \ - dst = prout(dst, fmt, _size); \ - if (dst != 0) \ - sp78.size += _size; \ - else \ - return sp78.size; \ - } -#define _PAD(i, m, c, src, extracond) \ - if (extracond && m > 0) \ - for (i = m; i > 0; i -= c) { \ - if ((u32) i > 32) \ - c = 32; \ - else \ - c = i; \ - _PROUT(dst, src, c); \ - } - -char spaces[] = " "; -char zeroes[] = "00000000000000000000000000000000"; - -static void _Putfld(printf_struct *, va_list *, fmt_type, fmt_type *); - -s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args) { - static const char flags_str[] = " +-#0"; - static const u32 flags_arr[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 }; - - printf_struct sp78; - const fmt_type *fmt_ptr; - fmt_type c; - const char *flag_index; - fmt_type sp4c[0x20]; // probably a buffer? - s32 sp48, sp44, sp40, sp3c, sp38, sp34, sp30, sp2c, sp28, sp24; - sp78.size = 0; - while (TRUE) { - fmt_ptr = (fmt_type *) fmt; -#if defined(VERSION_SH) || defined(VERSION_CN) - // new version: don't point fmt_ptr beyond NUL character - while ((c = *fmt_ptr) != 0 && c != '%') { - fmt_ptr++; - } -#else - while ((c = *fmt_ptr++) > 0) { - if (c == '%') { - fmt_ptr--; - break; - } - } -#endif - _PROUT(dst, fmt, fmt_ptr - (fmt_type *) fmt); - if (c == 0) { - return sp78.size; - } - fmt = (char *) ++fmt_ptr; - sp78.flags = 0; - for (; (flag_index = strchr(flags_str, *fmt_ptr)) != NULL; fmt_ptr++) { - sp78.flags |= flags_arr[flag_index - flags_str]; - } - if (*fmt_ptr == '*') { - sp78.width = va_arg(args, s32); - if (sp78.width < 0) { - sp78.width = -sp78.width; - sp78.flags |= FLAGS_MINUS; - } - fmt_ptr++; - } else { - ATOI(sp78.width, fmt_ptr); - } - if (*fmt_ptr != '.') { - sp78.precision = -1; - } else { - fmt_ptr++; - if (*fmt_ptr == '*') { - sp78.precision = va_arg(args, s32); - fmt_ptr++; - } else { - ATOI(sp78.precision, fmt_ptr); - } - } - sp78.length = strchr("hlL", *fmt_ptr) != NULL ? *fmt_ptr++ : '\0'; - - if (sp78.length == 'l' && *fmt_ptr == 'l') { - sp78.length = 'L'; - fmt_ptr++; - } - _Putfld(&sp78, &args, *fmt_ptr, sp4c); - sp78.width -= sp78.part1_len + sp78.num_leading_zeros + sp78.part2_len + sp78.num_mid_zeros - + sp78.part3_len + sp78.num_trailing_zeros; - _PAD(sp44, sp78.width, sp48, spaces, !(sp78.flags & FLAGS_MINUS)); - _PROUT(dst, (char *) sp4c, sp78.part1_len); - _PAD(sp3c, sp78.num_leading_zeros, sp40, zeroes, 1); - _PROUT(dst, sp78.buff, sp78.part2_len); - _PAD(sp34, sp78.num_mid_zeros, sp38, zeroes, 1); - _PROUT(dst, (char *) (&sp78.buff[sp78.part2_len]), sp78.part3_len) - _PAD(sp2c, sp78.num_trailing_zeros, sp30, zeroes, 1); - _PAD(sp24, sp78.width, sp28, spaces, sp78.flags & FLAGS_MINUS); - fmt = (char *) fmt_ptr + 1; - } -} - -static void _Putfld(printf_struct *a0, va_list *args, fmt_type type, fmt_type *buff) { - a0->part1_len = a0->num_leading_zeros = a0->part2_len = a0->num_mid_zeros = a0->part3_len = - a0->num_trailing_zeros = 0; - - switch (type) { - - case 'c': - buff[a0->part1_len++] = va_arg(*args, u32); - break; - - case 'd': - case 'i': - if (a0->length == 'l') { - a0->value.s64 = va_arg(*args, s32); - } else if (a0->length == 'L') { - a0->value.s64 = va_arg(*args, s64); - } else { - a0->value.s64 = va_arg(*args, s32); - } - - if (a0->length == 'h') { - a0->value.s64 = (s16) a0->value.s64; - } - - if (a0->value.s64 < 0) { - buff[a0->part1_len++] = '-'; - } else if (a0->flags & FLAGS_PLUS) { - buff[a0->part1_len++] = '+'; - } else if (a0->flags & FLAGS_SPACE) { - buff[a0->part1_len++] = ' '; - } - - a0->buff = (char *) &buff[a0->part1_len]; - - _Litob(a0, type); - break; - - case 'x': - case 'X': - case 'u': - case 'o': - if (a0->length == 'l') { - a0->value.s64 = va_arg(*args, s32); - } else if (a0->length == 'L') { - a0->value.s64 = va_arg(*args, s64); - } else { - a0->value.s64 = va_arg(*args, s32); - } - - if (a0->length == 'h') { - a0->value.s64 = (u16) a0->value.s64; - } else if (a0->length == 0) { - a0->value.s64 = (u32) a0->value.s64; - } - - if (a0->flags & FLAGS_HASH) { - buff[a0->part1_len++] = '0'; - if (type == 'x' || type == 'X') { - - buff[a0->part1_len++] = type; - } - } - a0->buff = (char *) &buff[a0->part1_len]; - _Litob(a0, type); - break; - - case 'e': - case 'f': - case 'g': - case 'E': - case 'G': - //... okay? - a0->value.f64 = a0->length == 'L' ? va_arg(*args, f64) : va_arg(*args, f64); - - if (a0->value.u16 & 0x8000) { - buff[a0->part1_len++] = '-'; - } else { - if (a0->flags & FLAGS_PLUS) { - buff[a0->part1_len++] = '+'; - } else if (a0->flags & FLAGS_SPACE) { - buff[a0->part1_len++] = ' '; - } - } - - a0->buff = (char *) &buff[a0->part1_len]; - _Ldtob(a0, type); - break; - - case 'n': - if (a0->length == 'h') { - *(va_arg(*args, u16 *)) = a0->size; - } else if (a0->length == 'l') { - *va_arg(*args, u32 *) = a0->size; - } else if (a0->length == 'L') { - *va_arg(*args, u64 *) = a0->size; - } else { - *va_arg(*args, u32 *) = a0->size; - } - break; - - case 'p': - a0->value.s64 = (intptr_t) va_arg(*args, void *); - a0->buff = (char *) &buff[a0->part1_len]; - _Litob(a0, 'x'); - break; - - case 's': - a0->buff = va_arg(*args, char *); - a0->part2_len = strlen(a0->buff); - if (a0->precision >= 0 && a0->part2_len > a0->precision) { - a0->part2_len = a0->precision; - } - break; - - case '%': - buff[a0->part1_len++] = '%'; - break; - - default: - buff[a0->part1_len++] = type; - break; - } -} diff --git a/lib/src/__osAtomicDec.c b/lib/src/__osAtomicDec.c deleted file mode 100644 index 87ff265e..00000000 --- a/lib/src/__osAtomicDec.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "libultra_internal.h" - -s32 __osAtomicDec(u32 *a0) { - s32 sp1c; - s32 sp18; - sp1c = __osDisableInt(); - - if (*a0 != 0) { - (*a0)--; - sp18 = 1; - } else { - sp18 = 0; - } - - __osRestoreInt(sp1c); - return sp18; -} diff --git a/lib/src/__osDequeueThread.c b/lib/src/__osDequeueThread.c deleted file mode 100644 index 42269232..00000000 --- a/lib/src/__osDequeueThread.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libultra_internal.h" - -// these don't feel like they belong here -// but it makes the most logical since there was printf data before -#ifndef AVOID_UB -OSThread *__osThreadTail = NULL; -u32 D_80334894 = -1; -OSThread *__osRunQueue = (OSThread *) &__osThreadTail; -OSThread *__osActiveQueue = (OSThread *) &__osThreadTail; -OSThread *__osRunningThread = { 0 }; -OSThread *__osFaultedThread = { 0 }; -#else -OSThread_ListHead __osThreadTail_fix = {NULL, -1, (OSThread *) &__osThreadTail_fix, (OSThread *) &__osThreadTail_fix, NULL, 0}; -#endif - -void __osDequeueThread(register OSThread **queue, register OSThread *thread) { - register OSThread **a2; - register OSThread *a3; - a2 = queue; - a3 = *a2; - while (a3 != NULL) { - if (a3 == thread) { - *a2 = thread->next; - return; - } - a2 = &a3->next; - a3 = *a2; - } -} diff --git a/lib/src/__osDevMgrMain.c b/lib/src/__osDevMgrMain.c deleted file mode 100644 index 3903c268..00000000 --- a/lib/src/__osDevMgrMain.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "libultra_internal.h" -#include "macros.h" -#include "PR/os.h" - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#include "new_func.h" -#include "PR/rcp.h" -#include "PR/ique.h" - -#define ALIGN16(val) (((val) + 0xF) & ~0xF) - -void __osDevMgrMain(void *args) { -#ifdef VERSION_CN - s32 loadedToTempBuffer = FALSE; -#endif - OSIoMesg *mb; - OSMesg em; - OSMesg dummy; - s32 ret; - OSMgrArgs *sp34; -#ifdef VERSION_EU - UNUSED u32 sp30; -#endif - u32 sp2c; - __OSBlockInfo *sp28; - __OSTranxInfo *sp24; -#if defined(VERSION_SH) || defined(VERSION_CN) - u32 tmp; -#endif -#ifdef VERSION_EU - sp30 = 0; -#endif - sp2c = 0; - mb = NULL; - ret = 0; - sp34 = (OSMgrArgs *) args; - while (TRUE) { - osRecvMesg(sp34->cmdQueue, (OSMesg) &mb, OS_MESG_BLOCK); - if (mb->piHandle != NULL && mb->piHandle->type == 2 - && (mb->piHandle->transferInfo.cmdType == 0 - || mb->piHandle->transferInfo.cmdType == 1)) { - sp24 = &mb->piHandle->transferInfo; - sp28 = &sp24->block[sp24->blockNum]; - sp24->sectorNum = -1; - if (sp24->transferMode != 3) { - sp28->dramAddr = (void *) ((u32) sp28->dramAddr - sp28->sectorSize); - } - if (sp24->transferMode == 2 && mb->piHandle->transferInfo.cmdType == 0) { - sp2c = 1; - } else { - sp2c = 0; - } - osRecvMesg(sp34->accessQueue, &dummy, OS_MESG_BLOCK); - __osResetGlobalIntMask(OS_IM_PI); - osEPiRawWriteIo(mb->piHandle, 0x05000510, (sp24->bmCtlShadow | 0x80000000)); -l1: - osRecvMesg(sp34->eventQueue, &em, OS_MESG_BLOCK); -#if defined(VERSION_SH) || defined(VERSION_CN) - sp24 = &mb->piHandle->transferInfo; - sp28 = &sp24->block[sp24->blockNum]; - if (sp28->errStatus == 0x1D) { - osEPiRawWriteIo(mb->piHandle, 0x5000510, sp24->bmCtlShadow | 0x10000000); - osEPiRawWriteIo(mb->piHandle, 0x5000510, sp24->bmCtlShadow); - osEPiRawReadIo(mb->piHandle, 0x5000508, &tmp); - if ((tmp & 0x2000000) != 0) { - osEPiRawWriteIo(mb->piHandle, 0x5000510, sp24->bmCtlShadow | 0x1000000); - } - sp28->errStatus = 4; - IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR); - __osSetGlobalIntMask(0x100C01); - } - - osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); - - if (sp2c == 1 && mb->piHandle->transferInfo.block[0].errStatus == 0) { - sp2c = 0; - goto l1; - } -#else - sp30 = osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); - - if (sp2c == 1 && mb->piHandle->transferInfo.errStatus == 0) { - sp2c = 0; - goto l1; - } -#endif - osSendMesg(sp34->accessQueue, NULL, OS_MESG_NOBLOCK); - - if (mb->piHandle->transferInfo.blockNum == 1) { - osYieldThread(); - } - } else { - switch (mb->hdr.type) { - case 11: - osRecvMesg(sp34->accessQueue, &dummy, OS_MESG_BLOCK); -#ifdef VERSION_CN - if (__osBbIsBb == 1 && ((uintptr_t) mb->dramAddr & 0x7f) >= 0x60) { - loadedToTempBuffer = TRUE; - ret = sp34->dma_func(OS_READ, mb->devAddr, (void *) 0x80600000, mb->size); - } else -#endif - ret = sp34->dma_func(OS_READ, mb->devAddr, mb->dramAddr, mb->size); - break; - case 12: - osRecvMesg(sp34->accessQueue, &dummy, OS_MESG_BLOCK); - ret = sp34->dma_func(OS_WRITE, mb->devAddr, mb->dramAddr, mb->size); - break; - case 15: - osRecvMesg(sp34->accessQueue, &dummy, OS_MESG_BLOCK); -#ifdef VERSION_CN - if (__osBbIsBb == 1 && ((uintptr_t) mb->dramAddr & 0x7f) >= 0x60) { - loadedToTempBuffer = TRUE; - ret = sp34->edma_func(mb->piHandle, OS_READ, mb->devAddr, (void *) 0x80600000, - mb->size); - } else -#endif - ret = sp34->edma_func(mb->piHandle, OS_READ, mb->devAddr, mb->dramAddr, - mb->size); - break; - case 16: - osRecvMesg(sp34->accessQueue, &dummy, OS_MESG_BLOCK); - ret = sp34->edma_func(mb->piHandle, OS_WRITE, mb->devAddr, mb->dramAddr, - mb->size); - break; - case 10: - osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); - ret = -1; - break; - break; - default: - ret = -1; - break; - } - if (ret == 0) { - osRecvMesg(sp34->eventQueue, &em, OS_MESG_BLOCK); -#ifdef VERSION_CN - if (__osBbIsBb == 1 && loadedToTempBuffer) { - osInvalDCache((void *) 0x80600000, ALIGN16(mb->size)); - bcopy((void *) 0x80600000, mb->dramAddr, mb->size); - osWritebackDCache(mb->dramAddr, mb->size); - loadedToTempBuffer = FALSE; - } -#endif -#ifdef VERSION_EU - sp30 = -#endif - osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); - osSendMesg(sp34->accessQueue, NULL, OS_MESG_NOBLOCK); - } - } - } -} -#else -void __osDevMgrMain(void *args) { - OSIoMesg *sp34; - OSMesg sp30; - OSMesg sp2c; - s32 sp28; - OSMgrArgs *sp24; - sp34 = NULL; - sp28 = 0; - sp24 = (OSMgrArgs *) args; - while (TRUE) { - osRecvMesg(sp24->cmdQueue, (OSMesg) &sp34, OS_MESG_BLOCK); - switch (sp34->hdr.type) { - case 11: - osRecvMesg(sp24->accessQueue, &sp2c, OS_MESG_BLOCK); - sp28 = sp24->dma_func(OS_READ, sp34->devAddr, sp34->dramAddr, sp34->size); - break; - case 12: - osRecvMesg(sp24->accessQueue, &sp2c, OS_MESG_BLOCK); - sp28 = sp24->dma_func(OS_WRITE, sp34->devAddr, sp34->dramAddr, sp34->size); - break; - case 10: - osSendMesg(sp34->hdr.retQueue, sp34, OS_MESG_NOBLOCK); - sp28 = -1; - break; - default: - sp28 = -1; - break; - } - if (sp28 == 0) { - osRecvMesg(sp24->eventQueue, &sp30, OS_MESG_BLOCK); - osSendMesg(sp34->hdr.retQueue, sp34, OS_MESG_NOBLOCK); - osSendMesg(sp24->accessQueue, NULL, OS_MESG_NOBLOCK); - } - } -} -#endif diff --git a/lib/src/__osGetCurrFaultedThread.c b/lib/src/__osGetCurrFaultedThread.c deleted file mode 100644 index eede93e1..00000000 --- a/lib/src/__osGetCurrFaultedThread.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "libultra_internal.h" - -OSThread *__osGetCurrFaultedThread() { - return __osActiveQueue; -} diff --git a/lib/src/__osPiCreateAccessQueue.c b/lib/src/__osPiCreateAccessQueue.c deleted file mode 100644 index 385848f9..00000000 --- a/lib/src/__osPiCreateAccessQueue.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "libultra_internal.h" - -#include "macros.h" - -#define PIAccessQueueSize 2 - -FORCE_BSS OSMesg osPiMesgBuff[PIAccessQueueSize]; -OSMesgQueue gOsPiMessageQueue; -u32 gOsPiAccessQueueCreated = 0; - -void __osPiCreateAccessQueue(void) { - gOsPiAccessQueueCreated = 1; - osCreateMesgQueue(&gOsPiMessageQueue, &osPiMesgBuff[0], PIAccessQueueSize - 1); - osSendMesg(&gOsPiMessageQueue, NULL, OS_MESG_NOBLOCK); -} - -void __osPiGetAccess(void) { - OSMesg sp1c; - if (!gOsPiAccessQueueCreated) { - __osPiCreateAccessQueue(); - } - osRecvMesg(&gOsPiMessageQueue, &sp1c, OS_MESG_BLOCK); -} - -void __osPiRelAccess(void) { - osSendMesg(&gOsPiMessageQueue, NULL, OS_MESG_NOBLOCK); -} diff --git a/lib/src/__osResetGlobalIntMask.c b/lib/src/__osResetGlobalIntMask.c deleted file mode 100644 index 26fbccfc..00000000 --- a/lib/src/__osResetGlobalIntMask.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "libultra_internal.h" -#include "PR/os.h" - -void __osResetGlobalIntMask(u32 mask) { - register u32 prev; - prev = __osDisableInt(); - __OSGlobalIntMask &= ~(-0x402 & mask); - __osRestoreInt(prev); -} diff --git a/lib/src/__osSetHWintrRoutine.c b/lib/src/__osSetHWintrRoutine.c deleted file mode 100644 index 0a32ede7..00000000 --- a/lib/src/__osSetHWintrRoutine.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "libultra_internal.h" - -extern s32 (*__osHwIntTable[])(void) ; - -void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void)) { - register u32 saveMask; - saveMask = __osDisableInt(); - __osHwIntTable[interrupt] = handler; - __osRestoreInt(saveMask); -} diff --git a/lib/src/__osSiCreateAccessQueue.c b/lib/src/__osSiCreateAccessQueue.c deleted file mode 100644 index 00f35011..00000000 --- a/lib/src/__osSiCreateAccessQueue.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "libultra_internal.h" - -#include "macros.h" - -#define SIAccessQueueSize 2 - -FORCE_BSS OSMesg osSiMesgBuff[SIAccessQueueSize]; -OSMesgQueue gOsSiMessageQueue; -u32 gOsSiAccessQueueCreated = 0; - -void __osSiCreateAccessQueue() { - gOsSiAccessQueueCreated = 1; - osCreateMesgQueue(&gOsSiMessageQueue, &osSiMesgBuff[0], SIAccessQueueSize - 1); - osSendMesg(&gOsSiMessageQueue, NULL, OS_MESG_NOBLOCK); -} - -void __osSiGetAccess(void) { - OSMesg sp1c; - if (!gOsSiAccessQueueCreated) { - __osSiCreateAccessQueue(); - } - osRecvMesg(&gOsSiMessageQueue, &sp1c, OS_MESG_BLOCK); -} - -void __osSiRelAccess(void) { - osSendMesg(&gOsSiMessageQueue, NULL, OS_MESG_NOBLOCK); -} diff --git a/lib/src/__osSiDeviceBusy.c b/lib/src/__osSiDeviceBusy.c deleted file mode 100644 index 83d5b395..00000000 --- a/lib/src/__osSiDeviceBusy.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -s32 __osSiDeviceBusy() { - register u32 status; - status = IO_READ(SI_STATUS_REG); - if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) { - return 1; - } else { - return 0; - } -} diff --git a/lib/src/__osSiRawStartDma.c b/lib/src/__osSiRawStartDma.c deleted file mode 100644 index 83b6b882..00000000 --- a/lib/src/__osSiRawStartDma.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "PR/ique.h" - -s32 __osSiRawStartDma(s32 dir, void *addr) { -#ifdef VERSION_CN - if (IO_READ(SI_STATUS_REG) & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) { - return -1; - } -#else - if (__osSiDeviceBusy()) { - return -1; - } -#endif - - if (dir == OS_WRITE) { - osWritebackDCache(addr, 64); - } - - IO_WRITE(SI_DRAM_ADDR_REG, osVirtualToPhysical(addr)); - - if (dir == OS_READ) { -#ifdef VERSION_CN - if (__osBbIsBb != 0) { - u32 prev = __osDisableInt(); - skKeepAlive(); - __osRestoreInt(prev); - } -#endif - IO_WRITE(SI_PIF_ADDR_RD64B_REG, 0x1FC007C0); - } else { - IO_WRITE(SI_PIF_ADDR_WR64B_REG, 0x1FC007C0); - } - - if (dir == OS_READ) { - osInvalDCache(addr, 64); - } - return 0; -} diff --git a/lib/src/__osSpDeviceBusy.c b/lib/src/__osSpDeviceBusy.c deleted file mode 100644 index e03b4543..00000000 --- a/lib/src/__osSpDeviceBusy.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -s32 __osSpDeviceBusy() { - register u32 status = IO_READ(SP_STATUS_REG); - - if (status & (SPSTATUS_IO_FULL | SPSTATUS_DMA_FULL | SPSTATUS_DMA_BUSY)) { - return 1; - } - - return 0; -} diff --git a/lib/src/__osSpRawStartDma.c b/lib/src/__osSpRawStartDma.c deleted file mode 100644 index 1f3f761d..00000000 --- a/lib/src/__osSpRawStartDma.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -s32 __osSpRawStartDma(u32 dir, void *sp_ptr, void *dram_ptr, size_t size) { - if (__osSpDeviceBusy()) { - return -1; - } - - IO_WRITE(SP_MEM_ADDR_REG, sp_ptr); - IO_WRITE(SP_DRAM_ADDR_REG, osVirtualToPhysical(dram_ptr)); - - if (dir == 0) { - IO_WRITE(SP_WR_LEN_REG, size - 1); - } else { - IO_WRITE(SP_RD_LEN_REG, size - 1); - } - return 0; -} diff --git a/lib/src/__osSpSetPc.c b/lib/src/__osSpSetPc.c deleted file mode 100644 index d72d5be1..00000000 --- a/lib/src/__osSpSetPc.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -s32 __osSpSetPc(void *pc) { - register u32 status = IO_READ(SP_STATUS_REG); - if (!(status & SPSTATUS_HALT)) { - return -1; - } else { - IO_WRITE(SP_PC_REG, pc); - return 0; - } -} diff --git a/lib/src/__osSpSetStatus.c b/lib/src/__osSpSetStatus.c deleted file mode 100644 index 975d34d7..00000000 --- a/lib/src/__osSpSetStatus.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -void __osSpSetStatus(u32 status) { - IO_WRITE(SP_STATUS_REG, status); -} diff --git a/lib/src/__osViGetCurrentContext.c b/lib/src/__osViGetCurrentContext.c deleted file mode 100644 index 0f7cf3a9..00000000 --- a/lib/src/__osViGetCurrentContext.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libultra_internal.h" - -extern OSViContext *__osViCurr; - -OSViContext *__osViGetCurrentContext() { - return __osViCurr; -} diff --git a/lib/src/__osViInit.c b/lib/src/__osViInit.c deleted file mode 100644 index 9643af04..00000000 --- a/lib/src/__osViInit.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "PR/os.h" - -OSViContext sViContexts[2] = { 0 }; -OSViContext *__osViCurr = &sViContexts[0]; -OSViContext *__osViNext = &sViContexts[1]; - -#ifdef VERSION_EU -u32 osViClock = VI_NTSC_CLOCK; -u32 sTvType = TV_TYPE_PAL; -#elif !defined(VERSION_SH) && !defined(VERSION_CN) -u32 sTvType = TV_TYPE_NTSC; -u32 osViClock = VI_NTSC_CLOCK; -#endif - -extern OSViMode osViModePalLan1; -extern OSViMode osViModeMpalLan1; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -extern OSViMode osViModeNtscLan1; -#endif - -void __osViInit(void) { -#ifdef VERSION_US - sTvType = osTvType; -#endif - - bzero(sViContexts, sizeof(sViContexts)); - __osViCurr = &sViContexts[0]; - __osViNext = &sViContexts[1]; - __osViNext->retraceCount = 1; - __osViCurr->retraceCount = 1; - -#if defined(VERSION_JP) - if (sTvType != TV_TYPE_PAL) { - __osViNext->modep = &osViModePalLan1; - osViClock = VI_NTSC_CLOCK; - } else { - __osViNext->modep = &osViModeMpalLan1; - osViClock = VI_PAL_CLOCK; - } -#elif defined(VERSION_US) - if (sTvType == TV_TYPE_NTSC) { - __osViNext->modep = &osViModePalLan1; - osViClock = VI_NTSC_CLOCK; - } else { - __osViNext->modep = &osViModeMpalLan1; - osViClock = VI_MPAL_CLOCK; - } -#elif defined(VERSION_EU) - if (osTvType == TV_TYPE_PAL) { - __osViNext->modep = &osViModePalLan1; - osViClock = VI_PAL_CLOCK; - } else if (osTvType == TV_TYPE_MPAL) { - __osViNext->modep = &osViModeMpalLan1; - osViClock = VI_MPAL_CLOCK; - } else { - __osViNext->modep = &osViModeNtscLan1; - osViClock = VI_NTSC_CLOCK; - } -#else - __osViNext->buffer = (void *) 0x80000000; - __osViCurr->buffer = (void *) 0x80000000; - if (osTvType == TV_TYPE_PAL) { - __osViNext->modep = &osViModePalLan1; - } else if (osTvType == TV_TYPE_MPAL) { - __osViNext->modep = &osViModeMpalLan1; - } else { - __osViNext->modep = &osViModeNtscLan1; - } - -#endif - - __osViNext->unk00 = VI_STATE_BLACK; - __osViNext->features = __osViNext->modep->comRegs.ctrl; - -#ifndef VERSION_JP - while (IO_READ(VI_CURRENT_REG) > 10) { - ; - } - IO_WRITE(VI_STATUS_REG, 0); -#endif - __osViSwapContext(); -} diff --git a/lib/src/__osViSwapContext.c b/lib/src/__osViSwapContext.c deleted file mode 100644 index 2aa963e6..00000000 --- a/lib/src/__osViSwapContext.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -extern OSViContext *__osViNext; -extern OSViContext *__osViCurr; - -extern u32 __additional_scanline; - -void __osViSwapContext() { - register OSViMode *viMode; - register OSViContext *s1; - u32 origin; - u32 hStart; -#ifdef VERSION_CN - u32 vStart; -#endif - u32 sp34; - u32 field; - field = 0; - s1 = __osViNext; - viMode = s1->modep; - field = IO_READ(VI_V_CURRENT_LINE_REG) & 1; - origin = osVirtualToPhysical(s1->buffer) + viMode->fldRegs[field].origin; - if (s1->unk00 & 2) { - s1->unk20 |= viMode->comRegs.xScale & ~0xfff; - } else { - s1->unk20 = viMode->comRegs.xScale; - } - if (s1->unk00 & 4) { - sp34 = (u32)(viMode->fldRegs[field].yScale & 0xfff); - s1->unk2c = s1->unk24 * sp34; - s1->unk2c |= viMode->fldRegs[field].yScale & ~0xfff; - } else { - s1->unk2c = viMode->fldRegs[field].yScale; - } - -#ifdef VERSION_CN - vStart = viMode->fldRegs[field].vStart - (__additional_scanline << 0x10) + __additional_scanline; -#endif - hStart = viMode->comRegs.hStart; - - if (s1->unk00 & 0x20) { - hStart = 0; - } - if (s1->unk00 & 0x40) { - s1->unk2c = 0; - origin = osVirtualToPhysical(s1->buffer); - } - if (s1->unk00 & 0x80) { - s1->unk2c = (s1->unk28 << 0x10) & 0x3ff0000; - origin = osVirtualToPhysical(s1->buffer); - } - IO_WRITE(VI_ORIGIN_REG, origin); - IO_WRITE(VI_WIDTH_REG, viMode->comRegs.width); - IO_WRITE(VI_BURST_REG, viMode->comRegs.burst); - IO_WRITE(VI_V_SYNC_REG, viMode->comRegs.vSync); - IO_WRITE(VI_H_SYNC_REG, viMode->comRegs.hSync); - IO_WRITE(VI_LEAP_REG, viMode->comRegs.leap); - IO_WRITE(VI_H_START_REG, hStart); -#ifdef VERSION_CN - IO_WRITE(VI_V_START_REG, vStart); -#else - IO_WRITE(VI_V_START_REG, viMode->fldRegs[field].vStart); -#endif - IO_WRITE(VI_V_BURST_REG, viMode->fldRegs[field].vBurst); - IO_WRITE(VI_INTR_REG, viMode->fldRegs[field].vIntr); - IO_WRITE(VI_X_SCALE_REG, s1->unk20); - IO_WRITE(VI_Y_SCALE_REG, s1->unk2c); - IO_WRITE(VI_CONTROL_REG, s1->features); - __osViNext = __osViCurr; - __osViCurr = s1; - *__osViNext = *__osViCurr; -} diff --git a/lib/src/alBnkfNew.c b/lib/src/alBnkfNew.c deleted file mode 100644 index 11db85bd..00000000 --- a/lib/src/alBnkfNew.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "libultra_internal.h" -#include "libaudio_internal.h" - -#define PATCH(SRC, BASE, TYPE) SRC = (TYPE)((uintptr_t) SRC + (uintptr_t) BASE) - -void alSeqFileNew(ALSeqFile *f, u8 *base) { - int i; - for (i = 0; i < f->seqCount; i++) { - PATCH(f->seqArray[i].offset, base, u8 *); - } -} - -static void _bnkfPatchBank(ALInstrument *inst, ALBankFile *f, u8 *table) { - int i; - ALSound *sound; - ALWaveTable *wavetable; - u8 *table2; - - if (inst->flags) { - return; - } - - inst->flags = 1; - - for (i = 0; i < inst->soundCount; i++) { - PATCH(inst->soundArray[i], f, ALSound *); - sound = inst->soundArray[i]; - if (sound->flags) { - continue; - } - - table2 = table; - - sound->flags = 1; - PATCH(sound->envelope, f, ALEnvelope *); - PATCH(sound->keyMap, f, ALKeyMap *); - PATCH(sound->wavetable, f, ALWaveTable *); - wavetable = sound->wavetable; - if (wavetable->flags) { - continue; - } - - wavetable->flags = 1; - PATCH(wavetable->base, table2, u8 *); - if (wavetable->type == 0) { - PATCH(wavetable->waveInfo.adpcmWave.book, f, ALADPCMBook *); - if (wavetable->waveInfo.adpcmWave.loop != NULL) { - PATCH(wavetable->waveInfo.adpcmWave.loop, f, ALADPCMloop *); - } - } else if (wavetable->type == 1) { - if (wavetable->waveInfo.rawWave.loop != NULL) { - PATCH(wavetable->waveInfo.rawWave.loop, f, ALRawLoop *); - } - } - } -} - -// Force adding another jr $ra. Has to be called or it doesn't get put in the -// right place. -static void unused(void) { -} - -void alBnkfNew(ALBankFile *f, u8 *table) { - ALBank *bank; - int i; - int j; - unused(); - if (f->revision != AL_BANK_VERSION) { - return; - } - - for (i = 0; i < f->bankCount; i++) { - PATCH(f->bankArray[i], f, ALBank *); - if (f->bankArray[i] == NULL) { - continue; - } - - bank = f->bankArray[i]; - if (bank->flags == 0) { - bank->flags = 1; - if (bank->percussion != NULL) { - PATCH(bank->percussion, f, ALInstrument *); - _bnkfPatchBank(bank->percussion, f, table); - } - for (j = 0; j < bank->instCount; j++) { - PATCH(bank->instArray[j], f, ALInstrument *); - if (bank->instArray[j] != NULL) { - _bnkfPatchBank(bank->instArray[j], f, table); - } - } - } - } -} diff --git a/lib/src/bstring.h b/lib/src/bstring.h deleted file mode 100644 index 01486d99..00000000 --- a/lib/src/bstring.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __BSTRING_H__ -#define __BSTRING_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/* - * bstring(3C) -- byte string operations - * - * Copyright 1990, Silicon Graphics, Inc. - * All Rights Reserved. - * - * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.; - * the contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of Silicon Graphics, Inc. - * - * RESTRICTED RIGHTS LEGEND: - * Use, duplication or disclosure by the Government is subject to restrictions - * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data - * and Computer Software clause at DFARS 252.227-7013, and/or in similar or - * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - - * rights reserved under the Copyright Laws of the United States. - */ - -#ident "$Revision: 1.4 $" - -extern void bcopy(const void *, void *, size_t); -extern int bcmp(const void *, const void *, int); -extern void bzero(void *, size_t); -extern void blkclr(void *, int); - -#ifdef __cplusplus -} -#endif -#endif /* !__BSTRING_H__ */ diff --git a/lib/src/contramread.c b/lib/src/contramread.c deleted file mode 100644 index 19cd3f53..00000000 --- a/lib/src/contramread.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "controller.h" -#include "macros.h" - -extern s32 __osPfsGetStatus(OSMesgQueue *, s32); -void __osPackRamReadData(int channel, u16 address); - -s32 __osContRamRead(OSMesgQueue *mq, int channel, u16 address, u8 *buffer) { - s32 ret; - int i; - u8 *ptr; - __OSContRamReadFormat ramreadformat; - int retry; - ret = 0; - ptr = (u8 *)&__osPfsPifRam; - retry = 2; - __osSiGetAccess(); - __osContLastCmd = CONT_CMD_READ_MEMPACK; - __osPackRamReadData(channel, address); - ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); - osRecvMesg(mq, NULL, OS_MESG_BLOCK); - do { - ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); - osRecvMesg(mq, NULL, OS_MESG_BLOCK); - ptr = (u8 *)&__osPfsPifRam; - if (channel != 0) { - for (i = 0; i < channel; i++) { - ptr++; - } - } - ramreadformat = *(__OSContRamReadFormat *)ptr; - ret = CHNL_ERR(ramreadformat); - if (ret == 0) { - u8 c; - c = __osContDataCrc((u8*)&ramreadformat.data); - if (c != ramreadformat.datacrc) { - ret = __osPfsGetStatus(mq, channel); - if (ret != 0) { - __osSiRelAccess(); - return ret; - } - ret = PFS_ERR_CONTRFAIL; - } else { - for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { - *buffer++ = ramreadformat.data[i]; - } - } - } else { - ret = PFS_ERR_NOPACK; - } - if (ret != PFS_ERR_CONTRFAIL) { - break; - } - } while (retry-- >= 0); - __osSiRelAccess(); - return ret; -} - -void __osPackRamReadData(int channel, u16 address) { - u8 *ptr; - __OSContRamReadFormat ramreadformat; - int i; - - ptr = (u8 *)__osPfsPifRam.ramarray; - - for (i = 0; i < ARRAY_COUNT(__osPfsPifRam.ramarray) + 1; i++) { - __osPfsPifRam.ramarray[i] = 0; - } - - __osPfsPifRam.pifstatus = CONT_CMD_EXE; - ramreadformat.dummy = CONT_CMD_NOP; - ramreadformat.txsize = CONT_CMD_READ_MEMPACK_TX; - ramreadformat.rxsize = CONT_CMD_READ_MEMPACK_RX; - ramreadformat.cmd = CONT_CMD_READ_MEMPACK; - ramreadformat.address = (address << 0x5) | __osContAddressCrc(address); - ramreadformat.datacrc = CONT_CMD_NOP; - for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { - ramreadformat.data[i] = CONT_CMD_NOP; - } - if (channel != 0) { - for (i = 0; i < channel; i++) { - *ptr++ = 0; - } - } - *(__OSContRamReadFormat *)ptr = ramreadformat; - ptr += sizeof(__OSContRamReadFormat); - ptr[0] = CONT_CMD_END; -} diff --git a/lib/src/contramwrite.c b/lib/src/contramwrite.c deleted file mode 100644 index abf21665..00000000 --- a/lib/src/contramwrite.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "controller.h" -#include "macros.h" - -extern s32 __osPfsGetStatus(OSMesgQueue *, s32); -void __osPackRamWriteData(s32 channel, u16 address, u8 *buffer); - -s32 __osContRamWrite(OSMesgQueue *mq, s32 channel, u16 address, u8 *buffer, s32 force) { - s32 ret; - s32 i; - u8 *ptr; - __OSContRamReadFormat ramreadformat; - s32 retry; - - ret = 0; - ptr = (u8 *)&__osPfsPifRam; - retry = 2; - if (force != 1 && address < 7 && address != 0) { - return 0; - } - __osSiGetAccess(); - __osContLastCmd = CONT_CMD_WRITE_MEMPACK; - __osPackRamWriteData(channel, address, buffer); - ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); - osRecvMesg(mq, NULL, OS_MESG_BLOCK); - do { - ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); - osRecvMesg(mq, NULL, OS_MESG_BLOCK); - ptr = (u8 *)&__osPfsPifRam; - if (channel != 0) { - for (i = 0; i < channel; i++) { - ptr++; - } - } - - ramreadformat = *(__OSContRamReadFormat *)ptr; - - ret = CHNL_ERR(ramreadformat); - if (ret == 0) { - if (__osContDataCrc(buffer) != ramreadformat.datacrc) { - ret = __osPfsGetStatus(mq, channel); - if (ret != 0) { - __osSiRelAccess(); - return ret; - } - ret = PFS_ERR_CONTRFAIL; - } - } else { - ret = PFS_ERR_NOPACK; - } - if (ret != PFS_ERR_CONTRFAIL) { - break; - } - } while ((retry-- >= 0)); - __osSiRelAccess(); - return ret; -} - -void __osPackRamWriteData(int channel, u16 address, u8 *buffer) { - u8 *ptr; - __OSContRamReadFormat ramreadformat; - int i; - - ptr = (u8 *)__osPfsPifRam.ramarray; - - for (i = 0; i < ARRAY_COUNT(__osPfsPifRam.ramarray) + 1; i++) { - __osPfsPifRam.ramarray[i] = 0; - } - - __osPfsPifRam.pifstatus = CONT_CMD_EXE; - ramreadformat.dummy = CONT_CMD_NOP; - ramreadformat.txsize = CONT_CMD_WRITE_MEMPACK_TX; - ramreadformat.rxsize = CONT_CMD_WRITE_MEMPACK_RX; - ramreadformat.cmd = CONT_CMD_WRITE_MEMPACK; - ramreadformat.address = (address << 0x5) | __osContAddressCrc(address); - ramreadformat.datacrc = CONT_CMD_NOP; - for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { - ramreadformat.data[i] = *buffer++; - } - if (channel != 0) { - for (i = 0; i < channel; i++) { - *ptr++ = 0; - } - } - *(__OSContRamReadFormat *)ptr = ramreadformat; - ptr += sizeof(__OSContRamReadFormat); - ptr[0] = CONT_CMD_END; -} diff --git a/lib/src/controller.h b/lib/src/controller.h deleted file mode 100644 index df67aa43..00000000 --- a/lib/src/controller.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef _CONTROLLER_H -#define _CONTROLLER_H -#include "PR/os_internal.h" -#include "PR/os.h" -#include "PR/rcp.h" - -//should go somewhere else but -#define CHNL_ERR(format) ((format.rxsize & CHNL_ERR_MASK) >> 4) - -typedef struct { - /* 0x00 */ u32 ramarray[15]; - /* 0x3C */ u32 pifstatus; -} OSPifRam; - -typedef struct { - /* 0x0 */ u8 dummy; - /* 0x1 */ u8 txsize; - /* 0x2 */ u8 rxsize; - /* 0x3 */ u8 cmd; - /* 0x4 */ u16 button; - /* 0x6 */ s8 stick_x; - /* 0x7 */ s8 stick_y; -} __OSContReadFormat; - -typedef struct { - /* 0x0 */ u8 dummy; - /* 0x1 */ u8 txsize; - /* 0x2 */ u8 rxsize; - /* 0x3 */ u8 cmd; - /* 0x4 */ u8 typeh; - /* 0x5 */ u8 typel; - /* 0x6 */ u8 status; - /* 0x7 */ u8 dummy1; -} __OSContRequesFormat; - -typedef struct { - /* 0x0 */ u8 txsize; - /* 0x1 */ u8 rxsize; - /* 0x2 */ u8 cmd; - /* 0x3 */ u8 typeh; - /* 0x4 */ u8 typel; - /* 0x5 */ u8 status; -} __OSContRequesFormatShort; - -typedef struct { - /* 0x0 */ u8 dummy; - /* 0x1 */ u8 txsize; - /* 0x2 */ u8 rxsize; - /* 0x3 */ u8 cmd; - /* 0x4 */ u16 address; - /* 0x6 */ u8 data[BLOCKSIZE]; - /* 0x26 */ u8 datacrc; -} __OSContRamReadFormat; - -typedef union { - /* 0x0 */ struct - { - /* 0x0 */ u8 bank; - /* 0x1 */ u8 page; - } inode_t; - /* 0x0 */ u16 ipage; -} __OSInodeUnit; - -typedef struct { - /* 0x0 */ u32 game_code; - /* 0x4 */ u16 company_code; - /* 0x6 */ __OSInodeUnit start_page; - /* 0x8 */ u8 status; - /* 0x9 */ s8 reserved; - /* 0xA */ u16 data_sum; - /* 0xC */ u8 ext_name[PFS_FILE_EXT_LEN]; - /* 0x10 */ u8 game_name[PFS_FILE_NAME_LEN]; -} __OSDir; - -typedef struct { - /* 0x0 */ __OSInodeUnit inode_page[128]; -} __OSInode; - -typedef struct { - /* 0x0 */ u32 repaired; - /* 0x4 */ u32 random; - /* 0x8 */ u64 serial_mid; - /* 0x10 */ u64 serial_low; - /* 0x18 */ u16 deviceid; - /* 0x1A */ u8 banks; - /* 0x1B */ u8 version; - /* 0x1C */ u16 checksum; - /* 0x1E */ u16 inverted_checksum; -} __OSPackId; - -typedef struct { - /* 0x0 */ u8 txsize; - /* 0x1 */ u8 rxsize; - /* 0x2 */ u8 cmd; - /* 0x3 */ u8 address; - /* 0x4 */ u8 data[EEPROM_BLOCK_SIZE]; -} __OSContEepromFormat; - -//from: http://en64.shoutwiki.com/wiki/SI_Registers_Detailed#CONT_CMD_Usage -#define CONT_CMD_REQUEST_STATUS 0 -#define CONT_CMD_READ_BUTTON 1 -#define CONT_CMD_READ_MEMPACK 2 -#define CONT_CMD_WRITE_MEMPACK 3 -#define CONT_CMD_READ_EEPROM 4 -#define CONT_CMD_WRITE_EEPROM 5 -#define CONT_CMD_RESET 0xff - -#define CONT_CMD_REQUEST_STATUS_TX 1 -#define CONT_CMD_READ_BUTTON_TX 1 -#define CONT_CMD_READ_MEMPACK_TX 3 -#define CONT_CMD_WRITE_MEMPACK_TX 35 -#define CONT_CMD_READ_EEPROM_TX 2 -#define CONT_CMD_WRITE_EEPROM_TX 10 -#define CONT_CMD_RESET_TX 1 - -#define CONT_CMD_REQUEST_STATUS_RX 3 -#define CONT_CMD_READ_BUTTON_RX 4 -#define CONT_CMD_READ_MEMPACK_RX 33 -#define CONT_CMD_WRITE_MEMPACK_RX 1 -#define CONT_CMD_READ_EEPROM_RX 8 -#define CONT_CMD_WRITE_EEPROM_RX 1 -#define CONT_CMD_RESET_RX 3 - -#define CONT_CMD_NOP 0xff -#define CONT_CMD_END 0xfe //indicates end of a command -#define CONT_CMD_EXE 1 //set pif ram status byte to this to do a command - -#define DIR_STATUS_EMPTY 0 -#define DIR_STATUS_UNKNOWN 1 -#define DIR_STATUS_OCCUPIED 2 - - -typedef struct -{ - /* 0x0 */ __OSInode inode; - /* 0x100 */ u8 bank; - /* 0x101 */ u8 map[256]; -} __OSInodeCache; - -extern s32 __osEepStatus(OSMesgQueue *, OSContStatus *); -u16 __osSumcalc(u8 *ptr, int length); -s32 __osIdCheckSum(u16 *ptr, u16 *csum, u16 *icsum); -s32 __osRepairPackId(OSPfs *pfs, __OSPackId *badid, __OSPackId *newid); -s32 __osCheckPackId(OSPfs *pfs, __OSPackId *temp); -s32 __osGetId(OSPfs *pfs); -s32 __osCheckId(OSPfs *pfs); -s32 __osPfsRWInode(OSPfs *pfs, __OSInode *inode, u8 flag, u8 bank); -s32 __osPfsSelectBank(OSPfs *pfs); -s32 __osPfsDeclearPage(OSPfs *pfs, __OSInode *inode, int file_size_in_pages, int *first_page, u8 bank, int *decleared, int *last_page); -s32 __osPfsReleasePages(OSPfs *pfs, __OSInode *inode, u8 start_page, u16 *sum, u8 bank, __OSInodeUnit *last_page, int flag); -s32 __osBlockSum(OSPfs *pfs, u8 page_no, u16 *sum, u8 bank); -s32 __osContRamRead(OSMesgQueue *mq, int channel, u16 address, u8 *buffer); -s32 __osContRamWrite(OSMesgQueue *mq, s32 channel, u16 address, u8 *buffer, s32 force); -void __osContGetInitData(u8 *pattern, OSContStatus *data); -void __osPackRequestData(u8 cmd); -void __osPfsRequestData(u8 cmd); -void __osPfsGetInitData(u8* pattern, OSContStatus* data); -u8 __osContAddressCrc(u16 addr); -u8 __osContDataCrc(u8 *data); -s32 __osPfsGetStatus(OSMesgQueue *queue, int channel); - -extern u8 __osContLastCmd; -extern OSTimer __osEepromTimer; -extern OSMesg __osEepromTimerMsg[4]; -extern OSMesgQueue __osEepromTimerQ; -extern OSPifRam __osEepPifRam; -extern OSPifRam __osContPifRam; -extern OSPifRam __osPfsPifRam; -extern u8 __osMaxControllers; - -//some version of this almost certainly existed since there's plenty of times where it's used right before a return 0 -#define ERRCK(fn) \ - ret = fn; \ - if (ret != 0) \ - return ret; - -#define SET_ACTIVEBANK_TO_ZERO \ - if (pfs->activebank != 0) \ - { \ - pfs->activebank = 0; \ - ERRCK(__osPfsSelectBank(pfs)) \ - } - -#define PFS_CHECK_ID \ - if (__osCheckId(pfs) == PFS_ERR_NEW_PACK) \ - return PFS_ERR_NEW_PACK; -#endif - -#define PFS_CHECK_STATUS \ - if ((pfs->status & PFS_INITIALIZED) == 0) \ - return PFS_ERR_INVALID; - -#define PFS_GET_STATUS \ - __osSiGetAccess(); \ - ret = __osPfsGetStatus(queue, channel); \ - __osSiRelAccess(); \ - if (ret != 0) \ - return ret; diff --git a/lib/src/crc.c b/lib/src/crc.c deleted file mode 100644 index f7fd3f29..00000000 --- a/lib/src/crc.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "libultra_internal.h" - -u8 __osContAddressCrc(u16 addr) { - u8 temp; - u8 temp2; - int i; - temp = 0; - for (i = 0; i < 16; i++) { - if (temp & 0x10) { - temp2 = 21; - } else { - temp2 = 0; - } - - temp <<= 1; - temp |= (u8)((addr & 0x400) ? 1 : 0); - addr <<= 1; - temp ^= temp2; - } - return temp & 0x1f; -} - -u8 __osContDataCrc(u8 *data) { - u8 temp; - u8 temp2; - int i; - int j; - temp = 0; - for (i = 0; i <= 32; i++, data++) { - for (j = 7; j >= 0; j--) { - if (temp & 0x80) { - temp2 = 133; - } else { - temp2 = 0; - } - temp <<= 1; - if (i == 32) { - temp &= -1; - } else { - temp |= ((*data & (1 << j)) ? 1 : 0); - } - temp ^= temp2; - } - } - return temp; -} diff --git a/lib/src/guMtxF2L.c b/lib/src/guMtxF2L.c deleted file mode 100644 index e2ec7a5a..00000000 --- a/lib/src/guMtxF2L.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "libultra_internal.h" -#ifdef GBI_FLOATS -#include -#endif - -#if !defined(VERSION_CN) || !defined(TARGET_N64) - -#ifndef GBI_FLOATS -void guMtxF2L(float mf[4][4], Mtx *m) { - int r, c; - s32 tmp1; - s32 tmp2; - s32 *m1 = &m->m[0][0]; - s32 *m2 = &m->m[2][0]; - for (r = 0; r < 4; r++) { - for (c = 0; c < 2; c++) { - tmp1 = mf[r][2 * c] * 65536.0f; - tmp2 = mf[r][2 * c + 1] * 65536.0f; - *m1++ = (tmp1 & 0xffff0000) | ((tmp2 >> 0x10) & 0xffff); - *m2++ = ((tmp1 << 0x10) & 0xffff0000) | (tmp2 & 0xffff); - } - } -} - -void guMtxL2F(float mf[4][4], Mtx *m) { - int r, c; - u32 tmp1; - u32 tmp2; - u32 *m1; - u32 *m2; - s32 stmp1, stmp2; - m1 = (u32 *) &m->m[0][0]; - m2 = (u32 *) &m->m[2][0]; - for (r = 0; r < 4; r++) { - for (c = 0; c < 2; c++) { - tmp1 = (*m1 & 0xffff0000) | ((*m2 >> 0x10) & 0xffff); - tmp2 = ((*m1++ << 0x10) & 0xffff0000) | (*m2++ & 0xffff); - stmp1 = *(s32 *) &tmp1; - stmp2 = *(s32 *) &tmp2; - mf[r][c * 2 + 0] = stmp1 / 65536.0f; - mf[r][c * 2 + 1] = stmp2 / 65536.0f; - } - } -} -#else -void guMtxF2L(float mf[4][4], Mtx *m) { - memcpy(m, mf, sizeof(Mtx)); -} -#endif - -void guMtxIdentF(float mf[4][4]) { - int r, c; - for (r = 0; r < 4; r++) { - for (c = 0; c < 4; c++) { - if (r == c) { - mf[r][c] = 1.0f; - } else { - mf[r][c] = 0.0f; - } - } - } -} - -void guMtxIdent(Mtx *m) { -#ifndef GBI_FLOATS - float mf[4][4]; - guMtxIdentF(mf); - guMtxF2L(mf, m); -#else - guMtxIdentF(m->m); -#endif -} - -#endif diff --git a/lib/src/guNormalize.c b/lib/src/guNormalize.c deleted file mode 100644 index 2f8a5aa3..00000000 --- a/lib/src/guNormalize.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libultra_internal.h" - -#if !defined(VERSION_CN) || !defined(TARGET_N64) - -void guNormalize(f32 *x, f32 *y, f32 *z) { - f32 tmp = 1.0f / sqrtf(*x * *x + *y * *y + *z * *z); - *x = *x * tmp; - *y = *y * tmp; - *z = *z * tmp; -} - -#endif diff --git a/lib/src/guOrthoF.c b/lib/src/guOrthoF.c deleted file mode 100644 index bf15b06c..00000000 --- a/lib/src/guOrthoF.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "libultra_internal.h" - -void guOrthoF(float m[4][4], float left, float right, float bottom, float top, float near, float far, - float scale) { - int row; - int col; - guMtxIdentF(m); - m[0][0] = 2 / (right - left); - m[1][1] = 2 / (top - bottom); - m[2][2] = -2 / (far - near); - m[3][0] = -(right + left) / (right - left); - m[3][1] = -(top + bottom) / (top - bottom); - m[3][2] = -(far + near) / (far - near); - m[3][3] = 1; - for (row = 0; row < 4; row++) { - for (col = 0; col < 4; col++) { - m[row][col] *= scale; - } - } -} - -void guOrtho(Mtx *m, float left, float right, float bottom, float top, float near, float far, - float scale) { - float sp28[4][4]; - guOrthoF(sp28, left, right, bottom, top, near, far, scale); - guMtxF2L(sp28, m); -} diff --git a/lib/src/guPerspectiveF.c b/lib/src/guPerspectiveF.c deleted file mode 100644 index f56fbb8f..00000000 --- a/lib/src/guPerspectiveF.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "libultra_internal.h" - -void guPerspectiveF(float mf[4][4], u16 *perspNorm, float fovy, float aspect, float near, float far, - float scale) { - float yscale; - int row; - int col; - guMtxIdentF(mf); - fovy *= GU_PI / 180.0; - yscale = cosf(fovy / 2) / sinf(fovy / 2); - mf[0][0] = yscale / aspect; - mf[1][1] = yscale; - mf[2][2] = (near + far) / (near - far); - mf[2][3] = -1; - mf[3][2] = 2 * near * far / (near - far); - mf[3][3] = 0.0f; - for (row = 0; row < 4; row++) { - for (col = 0; col < 4; col++) { - mf[row][col] *= scale; - } - } - if (perspNorm != NULL) { - if (near + far <= 2.0) { - *perspNorm = 65535; - } else { - *perspNorm = (double) (1 << 17) / (near + far); - if (*perspNorm <= 0) { - *perspNorm = 1; - } - } - } -} - -void guPerspective(Mtx *m, u16 *perspNorm, float fovy, float aspect, float near, float far, - float scale) { - float mat[4][4]; - guPerspectiveF(mat, perspNorm, fovy, aspect, near, far, scale); - guMtxF2L(mat, m); -} diff --git a/lib/src/guRotateF.c b/lib/src/guRotateF.c deleted file mode 100644 index 748265ba..00000000 --- a/lib/src/guRotateF.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "libultra_internal.h" - -void guRotateF(float m[4][4], float a, float x, float y, float z) { - static f32 pi_180 = GU_PI / 180.0f; - f32 sin_a; - f32 cos_a; - f32 ab; - f32 bc; - f32 ca; - f32 t; -#ifdef VERSION_CN - f32 xs; - f32 ys; - f32 zs; -#else - f32 xx, yy, zz; -#endif - - guNormalize(&x, &y, &z); - - a = a * pi_180; - - sin_a = sinf(a); - cos_a = cosf(a); - t = 1 - cos_a; - - ab = x * y * t; - bc = y * z * t; - ca = z * x * t; - - guMtxIdentF(m); - - // TODO: Merge IDO/GCC -#ifdef VERSION_CN - xs = x * sin_a; - t = x * x; - m[0][0] = t + cos_a * (1 - t); - m[2][1] = bc - xs; - m[1][2] = bc + xs; - - ys = y * sin_a; - t = y * y; - m[1][1] = t + cos_a * (1 - t); - m[2][0] = ca + ys; - m[0][2] = ca - ys; - - zs = z * sin_a; - t = z * z; - m[2][2] = t + cos_a * (1 - t); - m[1][0] = ab - zs; - m[0][1] = ab + zs; -#else - xx = x * x; - m[0][0] = xx + cos_a * (1 - xx); - m[2][1] = bc - (x * sin_a); - m[1][2] = bc + (x * sin_a); - - yy = y * y; - m[1][1] = yy + cos_a * (1 - yy); - m[2][0] = ca + (y * sin_a); - m[0][2] = ca - (y * sin_a); - - zz = z * z; - m[2][2] = zz + cos_a * (1 - zz); - m[1][0] = ab - (z * sin_a); - m[0][1] = ab + (z * sin_a); -#endif -} - -void guRotate(Mtx *m, float a, float x, float y, float z) { - float mf[4][4]; - guRotateF(mf, a, x, y, z); - guMtxF2L(mf, m); -} diff --git a/lib/src/guScaleF.c b/lib/src/guScaleF.c deleted file mode 100644 index b900a1e2..00000000 --- a/lib/src/guScaleF.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "libultra_internal.h" - -#if !defined(VERSION_CN) || !defined(TARGET_N64) - -void guScaleF(float mf[4][4], float x, float y, float z) { - guMtxIdentF(mf); - mf[0][0] = x; - mf[1][1] = y; - mf[2][2] = z; - mf[3][3] = 1.0; -} - -void guScale(Mtx *m, float x, float y, float z) { - float mf[4][4]; - guScaleF(mf, x, y, z); - guMtxF2L(mf, m); -} - -#endif diff --git a/lib/src/guTranslateF.c b/lib/src/guTranslateF.c deleted file mode 100644 index e0dc1f1e..00000000 --- a/lib/src/guTranslateF.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "libultra_internal.h" - -#if !defined(VERSION_CN) || !defined(TARGET_N64) - -void guTranslateF(float m[4][4], float x, float y, float z) { - guMtxIdentF(m); - m[3][0] = x; - m[3][1] = y; - m[3][2] = z; -} - -void guTranslate(Mtx *m, float x, float y, float z) { - float mf[4][4]; - guTranslateF(mf, x, y, z); - guMtxF2L(mf, m); -} - -#endif diff --git a/lib/src/kdebugserver_stack.c b/lib/src/kdebugserver_stack.c deleted file mode 100644 index 13f88633..00000000 --- a/lib/src/kdebugserver_stack.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "libultra_internal.h" - -#if defined(VERSION_JP) || defined(VERSION_US) -u8 debugBuffer[0x100]; -#endif diff --git a/lib/src/libaudio_internal.h b/lib/src/libaudio_internal.h deleted file mode 100644 index ea63322c..00000000 --- a/lib/src/libaudio_internal.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _LIBAUDIO_INTERNAL_H_ -#define _LIBAUDIO_INTERNAL_H_ -#include -#define AL_BANK_VERSION 0x4231 /* 'B1' */ - -typedef u8 ALPan; -typedef s32 ALMicroTime; - -/* Possible wavetable types */ -enum -{ - AL_ADPCM_WAVE = 0, - AL_RAW16_WAVE -}; - -typedef struct -{ - u32 start; - u32 end; - u32 count; -} ALRawLoop; - -typedef struct -{ - u32 start; - u32 end; - u32 count; - ADPCM_STATE state; -} ALADPCMloop; - -typedef struct -{ - s32 order; - s32 npredictors; - s16 book[1]; // variable size, 8-byte aligned -} ALADPCMBook; - -typedef struct -{ - ALMicroTime attackTime; - ALMicroTime decayTime; - ALMicroTime releaseTime; - u8 attackVolume; - u8 decayVolume; -} ALEnvelope; - -typedef struct -{ - u8 velocityMin; - u8 velocityMax; - u8 keyMin; - u8 keyMax; - u8 keyBase; - s8 detune; -} ALKeyMap; - -typedef struct -{ - ALADPCMloop *loop; - ALADPCMBook *book; -} ALADPCMWaveInfo; - -typedef struct -{ - ALRawLoop *loop; -} ALRAWWaveInfo; - -typedef struct ALWaveTable_s -{ - u8 *base; /* ptr to start of wave data */ - s32 len; /* length of data in bytes */ - u8 type; /* compression type */ - u8 flags; /* offset/address flags */ - union { - ALADPCMWaveInfo adpcmWave; - ALRAWWaveInfo rawWave; - } waveInfo; -} ALWaveTable; - -typedef struct ALSound_s -{ - ALEnvelope *envelope; - ALKeyMap *keyMap; - ALWaveTable *wavetable; /* offset to wavetable struct */ - ALPan samplePan; - u8 sampleVolume; - u8 flags; -} ALSound; - -typedef struct -{ - u8 volume; /* overall volume for this instrument */ - ALPan pan; /* 0 = hard left, 127 = hard right */ - u8 priority; /* voice priority for this instrument */ - u8 flags; - u8 tremType; /* the type of tremelo osc. to use */ - u8 tremRate; /* the rate of the tremelo osc. */ - u8 tremDepth; /* the depth of the tremelo osc */ - u8 tremDelay; /* the delay for the tremelo osc */ - u8 vibType; /* the type of tremelo osc. to use */ - u8 vibRate; /* the rate of the tremelo osc. */ - u8 vibDepth; /* the depth of the tremelo osc */ - u8 vibDelay; /* the delay for the tremelo osc */ - s16 bendRange; /* pitch bend range in cents */ - s16 soundCount; /* number of sounds in this array */ - ALSound *soundArray[1]; -} ALInstrument; - -typedef struct ALBank_s -{ - s16 instCount; /* number of programs in this bank */ - u8 flags; - u8 pad; - s32 sampleRate; /* e.g. 44100, 22050, etc... */ - ALInstrument *percussion; /* default percussion for GM */ - ALInstrument *instArray[1]; /* ARRAY of instruments */ -} ALBank; - -typedef struct -{ /* Note: sizeof won't be correct */ - s16 revision; /* format revision of this file */ - s16 bankCount; /* number of banks */ - ALBank *bankArray[1]; /* ARRAY of bank offsets */ -} ALBankFile; - -void alBnkfNew(ALBankFile *f, u8 *table); -#endif diff --git a/lib/src/libultra_internal.h b/lib/src/libultra_internal.h deleted file mode 100644 index bb7e2a0f..00000000 --- a/lib/src/libultra_internal.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _LIBULTRA_INTERNAL_H_ -#define _LIBULTRA_INTERNAL_H_ -#include - -/* - * This define is needed because the original definitions in __osDequeueThread.c are declared - * seperately instead of part of a single struct, however some code alises over this memory - * assuming a unified structure. To fix this, we declare the full type here and then alias the - * symbol names to the correct members in AVOID_UB. - */ -#ifdef AVOID_UB -typedef struct OSThread_ListHead_s -{ - /*0x00*/ struct OSThread_s *next; - /*0x04*/ OSPri priority; - /*0x08*/ struct OSThread_s *queue; - /*0x0C*/ struct OSThread_s *tlnext; - /*0x10*/ struct OSThread_s *unk10; - /*0x14*/ u32 unk14; -} OSThread_ListHead; - -// Now fix the symbols to the new one. -extern OSThread_ListHead __osThreadTail_fix; - -#define __osThreadTail __osThreadTail_fix.next -#define D_80334894 __osThreadTail_fix.priority -#define __osRunQueue __osThreadTail_fix.queue -#define __osActiveQueue __osThreadTail_fix.tlnext -#define __osRunningThread __osThreadTail_fix.unk10 -#else -// Original OSThread_ListHead definitions -extern OSThread *__osThreadTail; -extern u32 D_80334894; -extern OSThread *__osRunQueue; -extern OSThread *__osActiveQueue; -extern OSThread *__osRunningThread; -#endif - -typedef struct { - u32 initialized; // probably something like initialized? - OSThread *mgrThread; - OSMesgQueue *cmdQueue; - OSMesgQueue *eventQueue; - OSMesgQueue *accessQueue; - s32 (*dma_func)(s32, u32, void *, size_t); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - s32 (*edma_func)(OSPiHandle*, s32, u32, void *, size_t); -#else - u64 force_align; -#endif -} OSMgrArgs; - -s32 __osDisableInt(void); -void __osRestoreInt(s32); -void __osEnqueueAndYield(OSThread **); -void __osDequeueThread(OSThread **, OSThread *); -void __osEnqueueThread(OSThread **, OSThread *); -OSThread *__osPopThread(OSThread **); -s32 __osSiRawStartDma(s32, void *); -void __osSiCreateAccessQueue(void); -void __osSiGetAccess(void); -void __osSiRelAccess(void); -u32 __osProbeTLB(void *); -void __osPiCreateAccessQueue(void); -void __osPiGetAccess(void); -void __osSetSR(u32); -u32 __osGetSR(void); -void __osSetFpcCsr(u32); -s32 __osSiRawReadIo(u32, u32 *); -s32 __osSiRawWriteIo(u32, u32); -s32 osPiRawReadIo(u32, u32 *); -void __osSpSetStatus(u32); -u32 __osSpGetStatus(void); -s32 __osSpSetPc(void *); -s32 __osSpDeviceBusy(void); -s32 __osSiDeviceBusy(void); -s32 __osSpRawStartDma(u32 dir, void *sp_ptr, void *dram_ptr, size_t size); -void __osViInit(void); -OSViContext *__osViGetCurrentContext(void); -OSViContext *__osViGetCurrentContext2(void); -void __osViSwapContext(void); -void __osSetTimerIntr(u64); -u64 __osInsertTimer(OSTimer *); -void __osSetCompare(u32); -s32 __osAiDeviceBusy(void); -void __osDispatchThread(void); -u32 __osGetCause(void); -s32 __osAtomicDec(u32 *); -void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void)); -#endif diff --git a/lib/src/math/cosf.c b/lib/src/math/cosf.c deleted file mode 100644 index 9f74cf29..00000000 --- a/lib/src/math/cosf.c +++ /dev/null @@ -1,95 +0,0 @@ - -// These unions are necessary to put the constants in .rodata rather than .data. -// TODO: is it possible to remove them somehow? - -typedef union { - /* 0x0 */ double d; - /* 0x0 */ struct - { - /* 0x0 */ unsigned int hi; - /* 0x4 */ unsigned int lo; - } word; -} du; - -typedef union { - /* 0x0 */ float f; - /* 0x0 */ unsigned int i; -} fu; - -static const du P[5] = {{1.0}, - {-0.16666659550427756}, - {0.008333066246082155}, - {-1.980960290193795E-4}, - {2.605780637968037E-6}}; - -static const du rpi = {0.3183098861837907}; - -static const du pihi = { - 3.1415926218032837}; - -static const du pilo = { - 3.178650954705639E-8}; - -static const fu zero = {0.0}; -extern const fu NAN; - -float cosf(float x) -{ - double dx; // double x - double xsq; // x squared - double poly; - double dn; - float xabs; - int n; - double result; - int ix; // int x - int xpt; - ix = *(int *)&x; - xpt = (ix >> 22) & 0x1FF; - - if (xpt < 310) - { - if (0 < x) - xabs = x; - else - xabs = -x; - dx = xabs; - - dn = dx * rpi.d + .5; - if (0 <= dn) - { - n = dn + .5; - } - else - { - n = dn - .5; - } - dn = n; - - dn -= .5; - dx -= dn * pihi.d; - dx -= dn * pilo.d; - - xsq = dx * dx; - - poly = (((((P[4].d * xsq) + P[3].d) * xsq) + P[2].d) * xsq) + P[1].d; - - result = dx + ((dx * xsq) * poly); - - if ((n & 0x1) == 0) - { - return result; - } - else - { - return -(float)result; - } - } - - if (x != x) - { - return NAN.f; - } - - return zero.f; -} diff --git a/lib/src/math/llconv.c b/lib/src/math/llconv.c deleted file mode 100644 index 3cf941c1..00000000 --- a/lib/src/math/llconv.c +++ /dev/null @@ -1,34 +0,0 @@ -typedef signed long long int s64; -typedef unsigned long long int u64; -s64 __d_to_ll(double d) -{ - return d; -} -s64 __f_to_ll(float f) -{ - return f; -} -u64 __d_to_ull(double d) -{ - return d; -} -u64 __f_to_ull(float f) -{ - return f; -} -double __ll_to_d(s64 s) -{ - return s; -} -float __ll_to_f(s64 s) -{ - return s; -} -double __ull_to_d(u64 u) -{ - return u; -} -float __ull_to_f(u64 u) -{ - return u; -} diff --git a/lib/src/math/sinf.c b/lib/src/math/sinf.c deleted file mode 100644 index 0a5076c5..00000000 --- a/lib/src/math/sinf.c +++ /dev/null @@ -1,111 +0,0 @@ - -// These unions are necessary to put the constants in .rodata rather than .data. -// TODO: is it possible to remove them somehow? - -typedef union { - /* 0x0 */ double d; - /* 0x0 */ struct - { - /* 0x0 */ unsigned int hi; - /* 0x4 */ unsigned int lo; - } word; -} du; - -typedef union { - /* 0x0 */ float f; - /* 0x0 */ unsigned int i; -} fu; - -static const du P[5] = {{1.0}, - {-0.16666659550427756}, - {0.008333066246082155}, - {-1.980960290193795E-4}, - {2.605780637968037E-6}}; - -static const du rpi = {0.3183098861837907}; - -static const du pihi = { - 3.1415926218032837}; - -static const du pilo = { - 3.178650954705639E-8}; - -static const fu zero = {0.0}; -extern const fu NAN; - -float sinf(float x) -{ - double dx; // double x - double xsq; // x squared - double poly; - double dn; - int n; - double result; - int ix; // int x - int xpt; - - ix = *(int *)&x; - xpt = (ix >> 22) & 0x1FF; - - if (xpt < 255) - { - dx = x; - if (xpt >= 230) - { - xsq = dx * dx; - - poly = (((((P[4].d * xsq) + P[3].d) * xsq) + P[2].d) * xsq) + P[1].d; - - result = dx + ((dx * xsq) * poly); - - return result; - } - else - { - return x; - } - } - - if (xpt < 310) - { - dx = x; - - dn = dx * rpi.d; - - if (dn >= 0) - { - n = dn + 0.5; - } - else - { - n = dn - 0.5; - } - - dn = n; - - dx -= dn * pihi.d; - dx -= dn * pilo.d; - - xsq = dx * dx; - - poly = (((((P[4].d * xsq) + P[3].d) * xsq) + P[2].d) * xsq) + P[1].d; - - result = dx + ((dx * xsq) * poly); - - if ((n & 0x1) == 0) - { - return result; - } - else - { - return -(float)result; - } - } - - if (x != x) - { - return NAN.f; - } - - return zero.f; -} diff --git a/lib/src/motor.c b/lib/src/motor.c deleted file mode 100644 index acd58a4f..00000000 --- a/lib/src/motor.c +++ /dev/null @@ -1,193 +0,0 @@ -#include "PR/os_message.h" -#include "PR/os_pi.h" -#include "libultra_internal.h" -#include "controller.h" -#include "macros.h" - -#ifdef VERSION_CN - -s32 __osMotorAccess(UNUSED OSPfs *pfs, UNUSED s32 action) { - return PFS_ERR_INVALID; -} - -s32 osMotorInit(UNUSED OSMesgQueue *mq, UNUSED OSPfs *pfs, UNUSED int channel) { - return PFS_ERR_DEVICE; -} - -#else - -void _MakeMotorData(int channel, u16 address, u8 *buffer, OSPifRam *mdata); -u32 __osMotorinitialized[MAXCONTROLLERS] = { 0, 0, 0, 0 }; -OSPifRam _MotorStopData[MAXCONTROLLERS]; -OSPifRam _MotorStartData[MAXCONTROLLERS]; -u8 _motorstopbuf[32]; -u8 _motorstartbuf[32]; - -s32 osMotorStop(OSPfs *pfs) { - int i; - s32 ret; - u8 *ptr; - __OSContRamReadFormat ramreadformat; - ptr = (u8 *) &__osPfsPifRam; - - if (!__osMotorinitialized[pfs->channel]) { - return PFS_ERR_INVALID; - } - __osSiGetAccess(); - - __osContLastCmd = CONT_CMD_WRITE_MEMPACK; - __osSiRawStartDma(OS_WRITE, &_MotorStopData[pfs->channel]); - osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); - ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); - osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); - ptr = (u8 *) &__osPfsPifRam; - - if (pfs->channel != 0) { - for (i = 0; i < pfs->channel; i++) { - ptr++; - } - } - - ramreadformat = *(__OSContRamReadFormat *) ptr; - ret = CHNL_ERR(ramreadformat); - if (ret == 0 && ramreadformat.datacrc != __osContDataCrc((u8 *) &_motorstopbuf)) { - ret = PFS_ERR_CONTRFAIL; - } - __osSiRelAccess(); - return ret; -} - -s32 osMotorStart(OSPfs *pfs) { - int i; - s32 ret; - u8 *ptr; - __OSContRamReadFormat ramreadformat; - - ptr = (u8 *) &__osPfsPifRam; - - if (!__osMotorinitialized[pfs->channel]) { - return PFS_ERR_INVALID; - } - - __osSiGetAccess(); - - __osContLastCmd = CONT_CMD_WRITE_MEMPACK; - __osSiRawStartDma(OS_WRITE, &_MotorStartData[pfs->channel]); - osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); - ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); - osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); - ptr = (u8 *) &__osPfsPifRam; - - if (pfs->channel != 0) { - for (i = 0; i < pfs->channel; i++) { - ptr++; - } - } - - ramreadformat = *(__OSContRamReadFormat *) ptr; - ret = CHNL_ERR(ramreadformat); - if (ret == 0 && ramreadformat.datacrc != __osContDataCrc((u8 *) &_motorstartbuf)) { - ret = PFS_ERR_CONTRFAIL; - } - __osSiRelAccess(); - return ret; -} - -void _MakeMotorData(int channel, u16 address, u8 *buffer, OSPifRam *mdata) { - u8 *ptr; - __OSContRamReadFormat ramreadformat; - int i; - - ptr = (u8 *) mdata->ramarray; - for (i = 0; i < ARRAY_COUNT(mdata->ramarray); i++) { - mdata->ramarray[i] = 0; - } - mdata->pifstatus = CONT_CMD_EXE; - ramreadformat.dummy = CONT_CMD_NOP; - ramreadformat.txsize = CONT_CMD_WRITE_MEMPACK_TX; - ramreadformat.rxsize = CONT_CMD_WRITE_MEMPACK_RX; - ramreadformat.cmd = CONT_CMD_WRITE_MEMPACK; - - ramreadformat.address = (address << 0x5) | __osContAddressCrc(address); - ramreadformat.datacrc = CONT_CMD_NOP; - for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { - ramreadformat.data[i] = *buffer++; - } - if (channel != 0) { - for (i = 0; i < channel; i++) { - *ptr++ = 0; - } - } - *(__OSContRamReadFormat *) ptr = ramreadformat; - ptr += sizeof(__OSContRamReadFormat); - ptr[0] = CONT_CMD_END; -} - -s32 osMotorInit(OSMesgQueue *mq, OSPfs *pfs, int channel) { - int i; - s32 ret; - u8 temp[32]; - pfs->queue = mq; - pfs->channel = channel; - pfs->status = 0; - pfs->activebank = 128; - - for (i = 0; i < ARRAY_COUNT(temp); i++) { - temp[i] = 254; - } - - ret = __osContRamWrite(mq, channel, 1024, temp, FALSE); - if (ret == 2) { // TODO: remove magic constant - ret = __osContRamWrite(mq, channel, 1024, temp, FALSE); - } - if (ret != 0) { - return ret; - } - - ret = __osContRamRead(mq, channel, 1024, temp); - if (ret == 2) { - ret = PFS_ERR_CONTRFAIL; // is this right? - } - if (ret != 0) { - return ret; - } - if (temp[31] == 254) { - return PFS_ERR_DEVICE; - } - - for (i = 0; i < ARRAY_COUNT(temp); i++) { - temp[i] = 128; - } - - ret = __osContRamWrite(mq, channel, 1024, temp, FALSE); - if (ret == 2) { - ret = __osContRamWrite(mq, channel, 1024, temp, FALSE); - } - if (ret != 0) { - return ret; - } - - ret = __osContRamRead(mq, channel, 1024, temp); - if (ret == 2) { - ret = PFS_ERR_CONTRFAIL; - } - if (ret != 0) { - return ret; - } - if (temp[31] != 128) { - return PFS_ERR_DEVICE; - } - - if (!__osMotorinitialized[channel]) { - for (i = 0; i < ARRAY_COUNT(_motorstartbuf); i++) { - _motorstartbuf[i] = 1; - _motorstopbuf[i] = 0; - } - _MakeMotorData(channel, 1536, _motorstartbuf, &_MotorStartData[channel]); - _MakeMotorData(channel, 1536, _motorstopbuf, &_MotorStopData[channel]); - __osMotorinitialized[channel] = 1; - } - return 0; -} - -#endif diff --git a/lib/src/new_func.h b/lib/src/new_func.h deleted file mode 100644 index 824412da..00000000 --- a/lib/src/new_func.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NEW_FUNC_H -#define NEW_FUNC_H - -#include "libultra_internal.h" - -extern u32 osDDActive; - -void __osResetGlobalIntMask(u32 mask); -void osYieldThread(void); -#if defined(VERSION_SH) || defined(VERSION_CN) -void __osSetGlobalIntMask(s32 arg0); -#endif - -#endif diff --git a/lib/src/osAi.h b/lib/src/osAi.h deleted file mode 100644 index 276fa071..00000000 --- a/lib/src/osAi.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _OSAI_H_ -#define _OSAI_H_ - -s32 osAiSetFrequency(u32); -s32 osAiSetNextBuffer(void *, u32); -u32 osAiGetLength(void); -#endif diff --git a/lib/src/osAiSetNextBuffer.c b/lib/src/osAiSetNextBuffer.c deleted file mode 100644 index 10b7bd26..00000000 --- a/lib/src/osAiSetNextBuffer.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" - -/** - * It is worth noting that a previous hardware bug has been fixed by a software - * patch in osAiSetNextBuffer. This bug occurred when the address of the end of the - * buffer specified by osAiSetNextBuffer was at a specific value. This value - * occurred when the following was true: - * - * (vaddr + nbytes) & 0x00003FFF == 0x00002000 - * - * (when the buffer ends with address of lower 14 bits 0x2000) In this case, the - * DMA transfer does not complete successfully. This can cause clicks and pops in - * the audio output. This bug no longer requires special handling by the application - * because it is now patched by osAiSetNextBuffer. - */ - -s32 osAiSetNextBuffer(void *buff, u32 len) { - static u8 hdwrBugFlag = 0; - char *bptr; - -#ifdef VERSION_CN - if (__osAiDeviceBusy()) { - return -1; - } -#endif - - bptr = buff; - - if (hdwrBugFlag != 0) { - bptr -= 0x2000; - } - -#ifdef VERSION_CN - if ((((uintptr_t) buff + len) & 0x1fff) == 0) { -#else - if ((((uintptr_t) buff + len) & 0x3fff) == 0x2000) { -#endif - hdwrBugFlag = 1; - } else { - hdwrBugFlag = 0; - } - -#ifndef VERSION_CN - if (__osAiDeviceBusy()) { - return -1; - } -#endif - - IO_WRITE(AI_DRAM_ADDR_REG, osVirtualToPhysical(bptr)); - IO_WRITE(AI_LEN_REG, len); - return 0; -} diff --git a/lib/src/osCartRomInit.c b/lib/src/osCartRomInit.c deleted file mode 100644 index 937cf1e1..00000000 --- a/lib/src/osCartRomInit.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "PR/os_internal.h" -#include "PR/R4300.h" -#include "PR/rcp.h" -#include "PR/os_pi.h" -#include "PR/os.h" -#include "libultra_internal.h" -#include "piint.h" - -OSPiHandle __Dom1SpeedParam; - -#ifdef VERSION_CN - -OSPiHandle __CartRomHandle; - -OSPiHandle* osCartRomInit(void) { - register u32 a; - register s32 status; - register u32 prevInt; - register u32 lastLatency; - register u32 lastPageSize; - register u32 lastRelDuration; - register u32 lastPulse; - - static u32 notInitialized = 1; - - __osPiGetAccess(); - - if (!notInitialized) { - __osPiRelAccess(); - return &__CartRomHandle; - } - - notInitialized = 0; - __CartRomHandle.type = DEVICE_TYPE_CART; - __CartRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2); - __CartRomHandle.domain = 0; - __CartRomHandle.speed = 0; - bzero(&__CartRomHandle.transferInfo, sizeof(__OSTranxInfo)); - - WAIT_ON_IO_BUSY(status); - - lastLatency = IO_READ(PI_BSD_DOM1_LAT_REG); - lastPageSize = IO_READ(PI_BSD_DOM1_PGS_REG); - lastRelDuration = IO_READ(PI_BSD_DOM1_RLS_REG); - lastPulse = IO_READ(PI_BSD_DOM1_PWD_REG); - - IO_WRITE(PI_BSD_DOM1_LAT_REG, 0xff); - IO_WRITE(PI_BSD_DOM1_PGS_REG, 0); - IO_WRITE(PI_BSD_DOM1_RLS_REG, 3); - IO_WRITE(PI_BSD_DOM1_PWD_REG, 0xff); - - a = IO_READ(__CartRomHandle.baseAddress); - __CartRomHandle.latency = a & 0xFF; - __CartRomHandle.pageSize = (a >> 0x10) & 0xF; - __CartRomHandle.relDuration = (a >> 0x14) & 0xF; - __CartRomHandle.pulse = (a >> 8) & 0xFF; - - IO_WRITE(PI_BSD_DOM1_LAT_REG, lastLatency); - IO_WRITE(PI_BSD_DOM1_PGS_REG, lastPageSize); - IO_WRITE(PI_BSD_DOM1_RLS_REG, lastRelDuration); - IO_WRITE(PI_BSD_DOM1_PWD_REG, lastPulse); - - prevInt = __osDisableInt(); - __CartRomHandle.next = __osPiTable; - __osPiTable = &__CartRomHandle; - __osRestoreInt(prevInt); - __osPiRelAccess(); - - return &__CartRomHandle; -} - -#else - -OSPiHandle *osCartRomInit(void) { - u32 domain; - u32 saveMask; - - domain = 0; - - if (__Dom1SpeedParam.baseAddress == PHYS_TO_K1(PI_DOM1_ADDR2)) { - return &__Dom1SpeedParam; - } - - __Dom1SpeedParam.type = DEVICE_TYPE_CART; - __Dom1SpeedParam.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2); - osPiRawReadIo(0, &domain); - __Dom1SpeedParam.latency = domain & 0xff; - __Dom1SpeedParam.pulse = (domain >> 8) & 0xff; - __Dom1SpeedParam.pageSize = (domain >> 0x10) & 0xf; - __Dom1SpeedParam.relDuration = (domain >> 0x14) & 0xf; - __Dom1SpeedParam.domain = PI_DOMAIN1; - //__Dom1SpeedParam.speed = 0; - - bzero(&__Dom1SpeedParam.transferInfo, sizeof(__OSTranxInfo)); - - saveMask = __osDisableInt(); - __Dom1SpeedParam.next = __osPiTable; - __osPiTable = &__Dom1SpeedParam; - __osRestoreInt(saveMask); - - return &__Dom1SpeedParam; -} - -#endif diff --git a/lib/src/osContInit.c b/lib/src/osContInit.c deleted file mode 100644 index ce3aa8ab..00000000 --- a/lib/src/osContInit.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "libultra_internal.h" -#include "osContInternal.h" -#include "PR/os.h" -#include "controller.h" -#include "PR/ique.h" - -void __osPackRequestData(u8); -void __osContGetInitData(u8 *, OSContStatus *); - -u32 _osContInitialized = 0; // probably initialized - -#ifdef VERSION_CN -#define CLOCK_RATE (62500000ULL * 3 / 4) -#else -#define CLOCK_RATE osClockRate -#endif - -// these probably belong in EEPROMlongread or something -u8 __osContLastCmd; -u8 __osMaxControllers; -OSTimer __osEepromTimer; -OSMesgQueue __osEepromTimerQ; -OSMesg __osEepromTimerMsg[4]; - -s32 osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *status) { - OSMesg mesg; - u32 ret = 0; - OSTime currentTime; - OSTimer timer; - OSMesgQueue timerMesgQueue; - - if (_osContInitialized) { - return 0; - } - _osContInitialized = 1; - currentTime = osGetTime(); - if (500000 * CLOCK_RATE / 1000000 > currentTime) { - osCreateMesgQueue(&timerMesgQueue, &mesg, 1); - osSetTimer(&timer, 500000 * CLOCK_RATE / 1000000 - currentTime, 0, &timerMesgQueue, &mesg); - osRecvMesg(&timerMesgQueue, &mesg, OS_MESG_BLOCK); - } - __osMaxControllers = MAXCONTROLLERS; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - __osPackRequestData(0); -#else - __osPackRequestData(255); -#endif - ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray); - osRecvMesg(mq, &mesg, OS_MESG_BLOCK); - ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray); - osRecvMesg(mq, &mesg, OS_MESG_BLOCK); - __osContGetInitData(bitpattern, status); -#if defined(VERSION_EU) || defined(VERSION_SH) - __osContLastCmd = CONT_CMD_REQUEST_STATUS; -#elif defined(VERSION_CN) - __osContLastCmd = 0xfd; -#else - __osContLastCmd = CONT_CMD_RESET; -#endif - __osSiCreateAccessQueue(); - osCreateMesgQueue(&__osEepromTimerQ, __osEepromTimerMsg, 1); - return ret; -} - -void __osContGetInitData(u8 *bitpattern, OSContStatus *status) { - u8 *cmdBufPtr; - OSContPackedRequest response; - s32 i; - u8 sp7; - - sp7 = 0; - cmdBufPtr = (u8 *) __osContPifRam.ramarray; - for (i = 0; i < __osMaxControllers; i++, cmdBufPtr += sizeof(OSContPackedRequest), status++) { - response = *(OSContPackedRequest *) cmdBufPtr; - status->errnum = (response.rxLen & 0xc0) >> 4; - if (status->errnum == 0) { - status->type = response.data2 << 8 | response.data1; -#ifdef VERSION_CN - status->status = __osBbPakAddress[i] != NULL ? 1 : 0; -#else - status->status = response.data3; -#endif - - sp7 |= 1 << i; - } - } -#ifdef VERSION_CN - if (__osBbIsBb != 0 && __osBbHackFlags != 0) { - OSContStatus tmp; - status -= __osMaxControllers; - sp7 = (sp7 & ~((1 << __osBbHackFlags) | 1)) | - ((sp7 & 1) << __osBbHackFlags) | - ((sp7 & (1 << __osBbHackFlags)) >> __osBbHackFlags); - tmp = *status; - *status = status[__osBbHackFlags]; - status[__osBbHackFlags] = tmp; - } -#endif - *bitpattern = sp7; -} - -void __osPackRequestData(u8 command) { - u8 *cmdBufPtr; - OSContPackedRequest request; - s32 i; - -#ifdef VERSION_CN - for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray); i++) { -#else - for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray) + 1; i++) { -#endif - __osContPifRam.ramarray[i] = 0; - } - - __osContPifRam.pifstatus = 1; - cmdBufPtr = (u8 *) __osContPifRam.ramarray; - request.padOrEnd = 255; - request.txLen = 1; - request.rxLen = 3; - request.command = command; - request.data1 = 255; - request.data2 = 255; - request.data3 = 255; - request.data4 = 255; - - for (i = 0; i < __osMaxControllers; i++) { - * (OSContPackedRequest *) cmdBufPtr = request; - cmdBufPtr += sizeof(OSContPackedRequest); - } - *cmdBufPtr = 254; -} diff --git a/lib/src/osContInternal.h b/lib/src/osContInternal.h deleted file mode 100644 index 997fe4c9..00000000 --- a/lib/src/osContInternal.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _ULTRA64_CONTROLLER_INTERNAL_H_ -#define _ULTRA64_CONTROLLER_INTERNAL_H_ - -#include - -typedef struct -{ - u8 padOrEnd; - u8 txLen; - u8 rxLen; //includes errno - u8 command; - u16 button; - s8 rawStickX; - s8 rawStickY; -} OSContPackedRead; - -typedef struct -{ - u8 padOrEnd; - u8 txLen; - u8 rxLen; - u8 command; - u8 data1; - u8 data2; - u8 data3; - u8 data4; -} OSContPackedRequest; - -typedef union { - OSContPackedRead read; - OSContPackedRequest request; - u32 as_raw[2]; -} OSContPackedStruct; - -#endif diff --git a/lib/src/osContStartReadData.c b/lib/src/osContStartReadData.c deleted file mode 100644 index 0c7abcae..00000000 --- a/lib/src/osContStartReadData.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "libultra_internal.h" -#include "osContInternal.h" -#include "PR/ique.h" -#include -#include "controller.h" - -ALIGNED8 OSPifRam __osContPifRam; - -extern u8 __osContLastCmd; -extern u8 __osMaxControllers; - -void __osPackReadData(void); - -s32 osContStartReadData(OSMesgQueue *mesg) { -#ifdef VERSION_CN - s32 ret; -#else - s32 ret = 0; - s32 i; -#endif - __osSiGetAccess(); - if (__osContLastCmd != CONT_CMD_READ_BUTTON) { - __osPackReadData(); - ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray); - osRecvMesg(mesg, NULL, OS_MESG_BLOCK); - } -#ifndef VERSION_CN - for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray) + 1; i++) { - __osContPifRam.ramarray[i] = 0xff; - } - __osContPifRam.pifstatus = 0; -#endif - - ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray); -#ifdef VERSION_CN - __osContLastCmd = 0xfd; -#else - __osContLastCmd = CONT_CMD_READ_BUTTON; -#endif - __osSiRelAccess(); - return ret; -} - -void osContGetReadData(OSContPad *pad) { - u8 *cmdBufPtr; - OSContPackedRead response; - s32 i; - cmdBufPtr = (u8 *) __osContPifRam.ramarray; - for (i = 0; i < __osMaxControllers; i++, cmdBufPtr += sizeof(OSContPackedRead), pad++) { - response = * (OSContPackedRead *) cmdBufPtr; - pad->errnum = (response.rxLen & 0xc0) >> 4; - if (pad->errnum == 0) { - pad->button = response.button; - pad->stick_x = response.rawStickX; - pad->stick_y = response.rawStickY; - } - } -#ifdef VERSION_CN - if (__osBbIsBb != 0 && __osBbHackFlags != 0) { - OSContPad tmp; - pad -= __osMaxControllers; - tmp = *pad; - *pad = pad[__osBbHackFlags]; - pad[__osBbHackFlags] = tmp; - } -#endif -} - -void __osPackReadData() { - u8 *cmdBufPtr; - OSContPackedRead request; - s32 i; - cmdBufPtr = (u8 *) __osContPifRam.ramarray; - -#ifdef VERSION_CN - for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray); i++) { -#else - for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray) + 1; i++) { -#endif - __osContPifRam.ramarray[i] = 0; - } - - __osContPifRam.pifstatus = 1; - request.padOrEnd = 255; - request.txLen = 1; - request.rxLen = 4; - request.command = 1; - request.button = 65535; - request.rawStickX = -1; - request.rawStickY = -1; - for (i = 0; i < __osMaxControllers; i++) { - * (OSContPackedRead *) cmdBufPtr = request; - cmdBufPtr += sizeof(OSContPackedRead); - } - *cmdBufPtr = 254; -} diff --git a/lib/src/osCreateMesgQueue.c b/lib/src/osCreateMesgQueue.c deleted file mode 100644 index c8ac4901..00000000 --- a/lib/src/osCreateMesgQueue.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "libultra_internal.h" - -void osCreateMesgQueue(OSMesgQueue *mq, OSMesg *msgBuf, s32 count) { - mq->mtqueue = (OSThread *) &__osThreadTail; - mq->fullqueue = (OSThread *) &__osThreadTail; - mq->validCount = 0; - mq->first = 0; - mq->msgCount = count; - mq->msg = msgBuf; -} diff --git a/lib/src/osCreatePiManager.c b/lib/src/osCreatePiManager.c deleted file mode 100644 index 7014d9c3..00000000 --- a/lib/src/osCreatePiManager.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "libultra_internal.h" -#include "PR/os.h" -#include "piint.h" - -#include "macros.h" - -#define OS_PI_MGR_MESG_BUFF_SIZE 1 - -OSDevMgr __osPiDevMgr = { 0 }; - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -OSPiHandle *__osPiTable = NULL; -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) -OSPiHandle *__osCurrentHandle[2] = { &__Dom1SpeedParam, &__Dom2SpeedParam }; -#endif - -FORCE_BSS OSThread piMgrThread; -FORCE_BSS u32 piMgrStack[0x400]; // stack bottom -FORCE_BSS OSMesgQueue piEventQueue; -FORCE_BSS OSMesg piEventBuf[OS_PI_MGR_MESG_BUFF_SIZE + 1]; - -extern u32 gOsPiAccessQueueCreated; -extern OSMesgQueue gOsPiMessageQueue; -void __osDevMgrMain(void *); - -void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt) { - u32 int_disabled; - OSPri newPri; - OSPri currentPri; - - if (!__osPiDevMgr.active) { - osCreateMesgQueue(cmdQ, cmdBuf, cmdMsgCnt); - osCreateMesgQueue(&piEventQueue, &piEventBuf[0], OS_PI_MGR_MESG_BUFF_SIZE); - if (!gOsPiAccessQueueCreated) { - __osPiCreateAccessQueue(); - } // what is this constant geez - osSetEventMesg(OS_EVENT_PI, &piEventQueue, (void *) 0x22222222); - newPri = -1; - currentPri = osGetThreadPri(NULL); - if (currentPri < pri) { - newPri = currentPri; - osSetThreadPri(NULL, pri); - } - int_disabled = __osDisableInt(); - __osPiDevMgr.active = TRUE; - __osPiDevMgr.thread = &piMgrThread; - __osPiDevMgr.cmdQueue = cmdQ; - __osPiDevMgr.evtQueue = &piEventQueue; - __osPiDevMgr.acsQueue = &gOsPiMessageQueue; - __osPiDevMgr.dma = osPiRawStartDma; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - __osPiDevMgr.edma = osEPiRawStartDma; -#endif - osCreateThread(&piMgrThread, 0, __osDevMgrMain, (void *) &__osPiDevMgr, &piMgrStack[0x400], pri); - osStartThread(&piMgrThread); - __osRestoreInt(int_disabled); - if (newPri != -1) { - osSetThreadPri(NULL, newPri); - } - } -} diff --git a/lib/src/osCreateThread.c b/lib/src/osCreateThread.c deleted file mode 100644 index 1598dcbb..00000000 --- a/lib/src/osCreateThread.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "libultra_internal.h" -#include - -void __osCleanupThread(void); - -// Don't warn about pointer->u64 cast -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" - -void osCreateThread(OSThread *thread, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri pri) { - register u32 saveMask; - OSIntMask mask; - - thread->id = id; - thread->priority = pri; - thread->next = NULL; - thread->queue = NULL; - thread->context.pc = (u32) entry; - thread->context.a0 = (u64) arg; - thread->context.sp = (u64) sp - 16; - thread->context.ra = (u64) __osCleanupThread; - - mask = OS_IM_ALL; - thread->context.sr = (mask & OS_IM_CPU) | SR_EXL; - thread->context.rcp = (mask & RCP_IMASK) >> RCP_IMASKSHIFT; - thread->context.fpcsr = (u32) (FPCSR_FS | FPCSR_EV); - thread->fp = 0; - thread->state = OS_STATE_STOPPED; - thread->flags = 0; - saveMask = __osDisableInt(); - thread->tlnext = __osActiveQueue; - - __osActiveQueue = thread; - __osRestoreInt(saveMask); -} - -#pragma GCC diagnostic pop diff --git a/lib/src/osCreateViManager.c b/lib/src/osCreateViManager.c deleted file mode 100644 index f78c4cbd..00000000 --- a/lib/src/osCreateViManager.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "libultra_internal.h" - -#define OS_VI_MANAGER_MESSAGE_BUFF_SIZE 5 - -OSMgrArgs viMgrMainArgs = { 0 }; -static OSThread viMgrThread; -static u32 viMgrStack[0x400]; // stack bottom -static OSMesgQueue __osViMesgQueue; -static OSMesg viMgrMesgBuff[OS_VI_MANAGER_MESSAGE_BUFF_SIZE]; - -static OSIoMesg viEventViMesg; -static OSIoMesg viEventCounterMesg; - -extern void __osTimerServicesInit(void); -extern void __osTimerInterrupt(void); -extern OSTime __osCurrentTime; -extern u32 __osBaseCounter; -extern u32 __osViIntrCount; -void viMgrMain(void *); - -#ifdef VERSION_CN -u32 __additional_scanline = 0; -#endif - -void osCreateViManager(OSPri pri) { - u32 int_disabled; - OSPri newPri; - OSPri currentPri; - if (!viMgrMainArgs.initialized) { - __osTimerServicesInit(); -#ifdef VERSION_CN - __additional_scanline = 0; -#endif - osCreateMesgQueue(&__osViMesgQueue, &viMgrMesgBuff[0], OS_VI_MANAGER_MESSAGE_BUFF_SIZE); - viEventViMesg.hdr.type = 13; - viEventViMesg.hdr.pri = 0; - viEventViMesg.hdr.retQueue = 0; - viEventCounterMesg.hdr.type = 14; - viEventCounterMesg.hdr.pri = 0; - viEventCounterMesg.hdr.retQueue = 0; - osSetEventMesg(OS_EVENT_VI, &__osViMesgQueue, &viEventViMesg); - osSetEventMesg(OS_EVENT_COUNTER, &__osViMesgQueue, &viEventCounterMesg); - newPri = -1; - currentPri = osGetThreadPri(NULL); - if (currentPri < pri) { - newPri = currentPri; - osSetThreadPri(NULL, pri); - } - int_disabled = __osDisableInt(); - viMgrMainArgs.initialized = TRUE; - viMgrMainArgs.mgrThread = &viMgrThread; - viMgrMainArgs.cmdQueue = &__osViMesgQueue; - viMgrMainArgs.eventQueue = &__osViMesgQueue; - viMgrMainArgs.accessQueue = NULL; - viMgrMainArgs.dma_func = NULL; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - viMgrMainArgs.edma_func = NULL; -#endif - - osCreateThread(&viMgrThread, 0, viMgrMain, (void *) &viMgrMainArgs, &viMgrStack[0x400], pri); - __osViInit(); - osStartThread(&viMgrThread); - __osRestoreInt(int_disabled); - if (newPri != -1) { - osSetThreadPri(NULL, newPri); - } - } -} - -void viMgrMain(void *vargs) { - static u16 retrace; - OSViContext *context; - OSMgrArgs *args; - OSMesg mesg; - u32 sp28; // always 0 - u32 sp24; // time related - mesg = NULL; - sp28 = FALSE; - context = __osViGetCurrentContext(); - - if ((retrace = context->retraceCount) == 0) { - retrace = 1; - } - - args = (OSMgrArgs *) vargs; - - while (TRUE) { - osRecvMesg(args->eventQueue, &mesg, OS_MESG_BLOCK); - switch (*(u16 *) mesg) { - case 13: - __osViSwapContext(); - if (!--retrace) { - context = __osViGetCurrentContext(); - if (context->mq != NULL) { - osSendMesg(context->mq, context->msg, OS_MESG_NOBLOCK); - } - retrace = context->retraceCount; - } - __osViIntrCount++; - if (sp28) { - sp24 = osGetCount(); - __osCurrentTime = sp24; - sp28 = 0; - } - sp24 = __osBaseCounter; - __osBaseCounter = osGetCount(); - sp24 = __osBaseCounter - sp24; - __osCurrentTime = __osCurrentTime + sp24; - break; - - case 14: - __osTimerInterrupt(); - break; - } - } -} diff --git a/lib/src/osDestroyThread.c b/lib/src/osDestroyThread.c deleted file mode 100644 index 2f5c989d..00000000 --- a/lib/src/osDestroyThread.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "libultra_internal.h" - -void osDestroyThread(OSThread *thread) { - register s32 int_disabled; - register OSThread *s1; - register OSThread *s2; - - int_disabled = __osDisableInt(); - - if (thread == NULL) { - thread = __osRunningThread; - } else if (thread->state != OS_STATE_STOPPED) { - __osDequeueThread(thread->queue, thread); - } - - if (__osActiveQueue == thread) { - __osActiveQueue = __osActiveQueue->tlnext; - } else { - s1 = __osActiveQueue; -#ifdef VERSION_CN - while (s1->priority != -1) { - s2 = s1->tlnext; - if (s2 == thread) { - s1->tlnext = thread->tlnext; - break; - } - s1 = s2; - } -#else - s2 = s1->tlnext; - while (s2 != NULL) { - if (s2 == thread) { - s1->tlnext = thread->tlnext; - break; - } - s1 = s2; - s2 = s1->tlnext; - } -#endif - } - - if (thread == __osRunningThread) { - __osDispatchThread(); - } - - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osEPiRawStartDma.c b/lib/src/osEPiRawStartDma.c deleted file mode 100644 index 610b8583..00000000 --- a/lib/src/osEPiRawStartDma.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "PR/ique.h" -#include "new_func.h" -#include "PR/R4300.h" -#include "piint.h" - -// TODO: This define is from os.h, but including that causes problems... -#define PI_DOMAIN1 0 - -#if defined(VERSION_SH) || defined(VERSION_CN) -extern OSPiHandle *__osCurrentHandle[2]; -#endif - -s32 osEPiRawStartDma(OSPiHandle *pihandle, s32 dir, u32 devAddr, void *dram_addr, u32 size) { -#ifdef VERSION_CN - u64 dummyBuf[2]; - u32 status; - u32 domain; - u32 buf; - u32 mask; - u16 *tmp; - u32 i; - u32 end; -#elif defined(VERSION_SH) - u32 status; - u32 domain; -#else - register u32 status; -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) - EPI_SYNC(pihandle, status, domain); -#else - WAIT_ON_IO_BUSY(status); -#endif - -#ifdef VERSION_CN - if (dir == OS_READ) { - mask = 1; - - for (i = 1; i <= pihandle->pageSize + 2; i++) { - mask *= 2; - } - - if ((devAddr & (mask - 1)) == mask - 2) { - osEPiRawReadIo(pihandle, devAddr - 2, &buf); - - tmp = (u16 *) PHYS_TO_K1(dram_addr); - *(tmp++) = (u16) buf; - - devAddr += 2; - dram_addr = tmp; - size -= 2; - - if (size >= 4) { - osEPiRawReadIo(pihandle, devAddr, &buf); - - tmp = (u16 *) dram_addr; - *(tmp++) = buf >> 16; - *(tmp++) = (u16) buf; - - devAddr += 4; - dram_addr = tmp; - size -= 4; - - if (size != 0) { - osEPiRawReadIo(pihandle, devAddr, &buf); - - tmp = (u16 *) PHYS_TO_K1(dram_addr); - *(tmp++) = buf >> 16; - - devAddr += 2; - dram_addr = tmp; - size -= 2; - } - } - } - - end = devAddr + size; - - if (((end & (mask - 1)) == 2) | (size == 2)) { - if (end & 2) { - osEPiRawReadIo(pihandle, end - 2, &buf); - tmp = (u16 *) PHYS_TO_K1(dram_addr) + (size - 2) / 2; - *tmp = buf >> 16; - } else { - osEPiRawReadIo(pihandle, end - 4, &buf); - tmp = (u16 *) PHYS_TO_K1(dram_addr) + (size - 2) / 2; - *tmp = (u16) buf; - } - - size -= 2; - } - - if (size == 0) { - size = 8; - dram_addr = dummyBuf; - devAddr = 0; - } - } -#endif - - IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dram_addr)); - IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS(pihandle->baseAddress | devAddr)); - -#ifdef VERSION_CN - if ((u32) dir >= 2U) { - return -1; - } - - if ((pihandle->baseAddress | devAddr) <= 0x400) { - IO_WRITE(dir == OS_READ ? PI_EX_WR_LEN_REG : PI_EX_RD_LEN_REG, size - 1); - } else { - IO_WRITE(dir == OS_READ ? PI_WR_LEN_REG : PI_RD_LEN_REG, size - 1); - } -#else - switch (dir) { - case OS_READ: - IO_WRITE(PI_WR_LEN_REG, size - 1); - break; - case OS_WRITE: - IO_WRITE(PI_RD_LEN_REG, size - 1); - break; - default: - return -1; - } -#endif - return 0; -} - diff --git a/lib/src/osEepromLongRead.c b/lib/src/osEepromLongRead.c deleted file mode 100644 index 628690dc..00000000 --- a/lib/src/osEepromLongRead.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libultra_internal.h" -#include "controller.h" - -s32 osEepromLongRead(OSMesgQueue *mq, u8 address, u8 *buffer, s32 nbytes) { - s32 status = 0; - -#ifndef VERSION_CN - if (address > 0x40) { - return -1; - } -#endif - - while (nbytes > 0) { - status = osEepromRead(mq, address, buffer); - if (status != 0) { - return status; - } - - nbytes -= EEPROM_BLOCK_SIZE; - address++; - buffer += EEPROM_BLOCK_SIZE; -#ifndef VERSION_CN - osSetTimer(&__osEepromTimer, 12000 * osClockRate / 1000000, 0, &__osEepromTimerQ, __osEepromTimerMsg); - osRecvMesg(&__osEepromTimerQ, NULL, OS_MESG_BLOCK); -#endif - } - - return status; -} diff --git a/lib/src/osEepromLongWrite.c b/lib/src/osEepromLongWrite.c deleted file mode 100644 index 97ae82d9..00000000 --- a/lib/src/osEepromLongWrite.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "libultra_internal.h" -#include "controller.h" - -#ifdef VERSION_CN -#define CLOCK_RATE (62500000ULL * 3 / 4) -#else -#define CLOCK_RATE osClockRate -#endif - -s32 osEepromLongWrite(OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) { - s32 result = 0; -#ifndef VERSION_CN - if (address > 0x40) { - return -1; - } -#endif - - while (nbytes > 0) { - result = osEepromWrite(mq, address, buffer); - if (result != 0) { - return result; - } - - nbytes -= EEPROM_BLOCK_SIZE; - address++; - buffer += EEPROM_BLOCK_SIZE; - osSetTimer(&__osEepromTimer, 12000 * CLOCK_RATE / 1000000, 0, &__osEepromTimerQ, __osEepromTimerMsg); - osRecvMesg(&__osEepromTimerQ, NULL, OS_MESG_BLOCK); - } - - return result; -} diff --git a/lib/src/osEepromProbe.c b/lib/src/osEepromProbe.c deleted file mode 100644 index 5924906e..00000000 --- a/lib/src/osEepromProbe.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "macros.h" -#include "libultra_internal.h" - -extern u32 __osBbEepromSize; - -s32 __osEepStatus(OSMesgQueue *, OSContStatus *); -s32 osEepromProbe(UNUSED OSMesgQueue *mq) { - s32 ret = 0; -#ifndef VERSION_CN - OSContStatus status; -#endif - - __osSiGetAccess(); -#ifdef VERSION_CN - if (__osBbEepromSize == 0x200) { - ret = EEPROM_TYPE_4K; - } else if (__osBbEepromSize == 0x800) { - ret = EEPROM_TYPE_16K; - } -#else - ret = __osEepStatus(mq, &status); - ret = (ret == 0 && (status.type & CONT_EEPROM) != 0) ? EEPROM_TYPE_4K : 0; -#endif - __osSiRelAccess(); - return ret; -} diff --git a/lib/src/osEepromRead.c b/lib/src/osEepromRead.c deleted file mode 100644 index 26de2b62..00000000 --- a/lib/src/osEepromRead.c +++ /dev/null @@ -1,115 +0,0 @@ -#include "libultra_internal.h" -#include "PR/ique.h" -#include "controller.h" -#include "macros.h" - -#ifdef VERSION_CN - -s32 osEepromRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer) { - s32 ret = 0; - s32 i; - - __osSiGetAccess(); - - if (__osBbEepromSize == 0x200) { - if (address >= 0x200 / 8) { - ret = -1; - } - } else if (__osBbEepromSize != 0x800) { - ret = 8; - } - - if (ret == 0) { - for (i = 0; i < 8; i++) { - buffer[i] = (__osBbEepromAddress + address * 8)[i]; - } - } - - __osSiRelAccess(); - return ret; -} - -#else - -void __osPackEepReadData(u8); - -s32 osEepromRead(OSMesgQueue *mq, u8 address, u8 *buffer) { - s32 ret = 0; - s32 i = 0; - u8 *ptr = (u8 *) &__osEepPifRam.ramarray; - OSContStatus sdata; - __OSContEepromFormat eepromformat; - - if (address > EEPROM_MAXBLOCKS) { - return -1; - } - - __osSiGetAccess(); - ret = __osEepStatus(mq, &sdata); - if (ret != 0 || sdata.type != CONT_EEPROM) { - - return CONT_NO_RESPONSE_ERROR; - } - - while (sdata.status & CONT_EEPROM_BUSY) { - __osEepStatus(mq, &sdata); - } - __osPackEepReadData(address); - - ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); - osRecvMesg(mq, NULL, OS_MESG_BLOCK); - - for (i = 0; i < ARRAY_COUNT(__osEepPifRam.ramarray) + 1; i++) { - __osEepPifRam.ramarray[i] = CONT_CMD_NOP; - } - __osEepPifRam.pifstatus = 0; - - ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); - __osContLastCmd = CONT_CMD_READ_EEPROM; - osRecvMesg(mq, NULL, OS_MESG_BLOCK); - - for (i = 0; i < 4; i++) { - ptr++; - } - - eepromformat = *(__OSContEepromFormat *) ptr; - ret = CHNL_ERR(eepromformat); - - if (ret == 0) { - for (i = 0; i < 8; i++) { - *buffer++ = eepromformat.data[i]; - } - } - - __osSiRelAccess(); - return ret; -} - -void __osPackEepReadData(u8 address) { - u8 *ptr = (u8 *) &__osEepPifRam.ramarray; - __OSContEepromFormat eepromformat; - s32 i; - - for (i = 0; i < ARRAY_COUNT(__osEepPifRam.ramarray) + 1; i++) { - __osEepPifRam.ramarray[i] = CONT_CMD_NOP; - } - __osEepPifRam.pifstatus = CONT_CMD_EXE; - - eepromformat.txsize = CONT_CMD_READ_EEPROM_TX; - eepromformat.rxsize = CONT_CMD_READ_EEPROM_RX; - eepromformat.cmd = CONT_CMD_READ_EEPROM; - eepromformat.address = address; - for (i = 0; i < ARRAY_COUNT(eepromformat.data); i++) { - eepromformat.data[i] = 0; - } - - for (i = 0; i < 4; i++) { - *ptr++ = 0; - } - - *(__OSContEepromFormat *) ptr = eepromformat; - ptr += sizeof(__OSContEepromFormat); - *ptr = CONT_CMD_END; -} - -#endif diff --git a/lib/src/osInitialize.c b/lib/src/osInitialize.c deleted file mode 100644 index 33c182df..00000000 --- a/lib/src/osInitialize.c +++ /dev/null @@ -1,182 +0,0 @@ -#include "libultra_internal.h" -#include "PR/R4300.h" -#include "piint.h" -#include "PR/rcp.h" -#include "PR/ique.h" -#include - -typedef struct { - u32 inst1; - u32 inst2; - u32 inst3; - u32 inst4; -} __osExceptionVector; -extern __osExceptionVector __osExceptionPreamble; - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -extern u32 __osSetHWintrRoutine(OSHWIntr, s32 (*)); -extern s32 __osLeoInterrupt(void); -#endif - -u32 __osFinalrom; // maybe initialized? -u64 osClockRate = OS_CLOCK_RATE; - -#if defined(VERSION_SH) || defined(VERSION_CN) -u32 osViClock = VI_NTSC_CLOCK; -#endif - -u32 __osShutdown = 0; // used in __osException - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -u32 EU_D_80336C40; -u32 EU_D_80336C44; - -u32 __OSGlobalIntMask = OS_IM_ALL; -u32 osDDActive = 0; -u8 EU_unusedZeroes[8] = { 0 }; -#endif - - -#ifdef VERSION_CN - -void __createSpeedParam(void) { - __Dom1SpeedParam.type = DEVICE_TYPE_INIT; - __Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG); - __Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG); - __Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG); - __Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG); - - __Dom2SpeedParam.type = DEVICE_TYPE_INIT; - __Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG); - __Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG); - __Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG); - __Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG); -} -#endif - -#ifdef VERSION_CN -void __osInitialize_common(void) -#else -void osInitialize(void) -#endif -{ - u32 pifdata; -#ifndef VERSION_CN - u32 clock = 0; -#endif -#ifdef VERSION_CN - u32 intrMask1, intrMask2; -#endif - -#ifdef VERSION_EU - u32 leoStatus; - u32 status; -#endif - - UNUSED u32 ptr; - - __osFinalrom = TRUE; - __osSetSR(__osGetSR() | SR_CU1); - __osSetFpcCsr(FPCSR_FS | FPCSR_EV); -#ifdef VERSION_CN - __osSetWatchLo(0x4900000); - intrMask1 = IO_WRITE(MI_HW_INTR_MASK_REG, 0x22000); - intrMask2 = IO_WRITE(MI_HW_INTR_MASK_REG, 0x11000); - __osBbIsBb = (intrMask1 & 0x140) == 0x140 && (intrMask2 & 0x140) == 0 ? 1 : 0; - if (__osBbIsBb != 0 && (IO_READ(PI_MISC_REG) & 0xC0000000) != 0) { - __osBbIsBb = 2; - } - if (__osBbIsBb != 0) { - osTvType = TV_TYPE_NTSC; - osRomType = DEVICE_TYPE_CART; - osResetType = RESET_TYPE_COLD_RESET; - osVersion = 1; - osMemSize = 4 * 1024 * 1024; - } - if (__osBbIsBb == 0) { -#endif - while (__osSiRawReadIo(PIF_RAM_END - 3, &pifdata)) { - ; - } - while (__osSiRawWriteIo(PIF_RAM_END - 3, pifdata | 8)) { - ; - } -#ifdef VERSION_CN - } -#endif - *(__osExceptionVector *) UT_VEC = __osExceptionPreamble; - *(__osExceptionVector *) XUT_VEC = __osExceptionPreamble; - *(__osExceptionVector *) ECC_VEC = __osExceptionPreamble; - *(__osExceptionVector *) E_VEC = __osExceptionPreamble; - osWritebackDCache((void *) UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector)); - osInvalICache((void *) UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector)); -#ifdef VERSION_CN - __createSpeedParam(); - osUnmapTLBAll(); -#endif - osMapTLBRdb(); -#ifndef VERSION_CN - osPiRawReadIo(4, &clock); - clock &= ~0xf; - if (clock) { - osClockRate = clock; - } -#endif - osClockRate = osClockRate * 3 / 4; - if (osResetType == RESET_TYPE_COLD_RESET) { - bzero(osAppNmiBuffer, sizeof(osAppNmiBuffer)); - } -#if defined(VERSION_SH) || defined(VERSION_CN) - if (osTvType == TV_TYPE_PAL) { - osViClock = VI_PAL_CLOCK; - } else if (osTvType == TV_TYPE_MPAL) { - osViClock = VI_MPAL_CLOCK; - } else { - osViClock = VI_NTSC_CLOCK; - } -#elif defined(VERSION_EU) - WAIT_ON_IO_BUSY(status); - - if (!((leoStatus = IO_READ(LEO_STATUS)) & LEO_STATUS_PRESENCE_MASK)) { - osDDActive = 1; - __osSetHWIntrRoutine(1, __osLeoInterrupt); - } else { - osDDActive = 0; - } -#endif - -#ifdef VERSION_CN - if (__osGetCause() & 0x1000) { - while (TRUE) { - } - } - if (__osBbIsBb == 0) { - __osBbEepromSize = 0x200; - __osBbPakSize = 0x8000; - __osBbFlashSize = 0x20000; - __osBbEepromAddress = (u8 *) 0x803FFE00; - __osBbPakAddress[0] = (u32 *) 0x803F7E00; - __osBbPakAddress[1] = NULL; - __osBbPakAddress[2] = NULL; - __osBbPakAddress[3] = NULL; - __osBbFlashAddress = 0x803E0000; - __osBbSramSize = __osBbFlashSize; - __osBbSramAddress = __osBbFlashAddress; - } - if (__osBbIsBb != 0) { - IO_WRITE(PI_BASE_REG+0x64, IO_READ(PI_BASE_REG+0x64) & 0x7FFFFFFF); - IO_WRITE(MI_HW_INTR_MASK_REG, 0x20000); - IO_WRITE(SI_BASE_REG+0x0C, 0); // a "reserved" register - IO_WRITE(SI_BASE_REG+0x1C, (IO_READ(SI_BASE_REG+0x1C) & 0x80FFFFFF) | 0x2F400000); - } - - IO_WRITE(AI_CONTROL_REG, 1); - IO_WRITE(AI_DACRATE_REG, 0x3fff); - IO_WRITE(AI_BITRATE_REG, 0xf); -#endif -} - -#ifdef VERSION_CN -void __osInitialize_autodetect(void) { -} -#endif diff --git a/lib/src/osLeoDiskInit.c b/lib/src/osLeoDiskInit.c deleted file mode 100644 index 32176cee..00000000 --- a/lib/src/osLeoDiskInit.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "PR/os.h" - -OSPiHandle __Dom2SpeedParam; -OSPiHandle *__osDiskHandle; - -OSPiHandle *osLeoDiskInit(void) { - s32 saveMask; - - __Dom2SpeedParam.type = DEVICE_TYPE_64DD; - __Dom2SpeedParam.baseAddress = PHYS_TO_K1(PI_DOM2_ADDR1); - __Dom2SpeedParam.latency = 3; - __Dom2SpeedParam.pulse = 6; - __Dom2SpeedParam.pageSize = 6; - __Dom2SpeedParam.relDuration = 2; -#ifdef VERSION_SH - __Dom2SpeedParam.domain = 1; -#endif - IO_WRITE(PI_BSD_DOM2_LAT_REG, __Dom2SpeedParam.latency); - IO_WRITE(PI_BSD_DOM2_PWD_REG, __Dom2SpeedParam.pulse); - IO_WRITE(PI_BSD_DOM2_PGS_REG, __Dom2SpeedParam.pageSize); - IO_WRITE(PI_BSD_DOM2_RLS_REG, __Dom2SpeedParam.relDuration); - bzero(&__Dom2SpeedParam.transferInfo, sizeof(__OSTranxInfo)); - saveMask = __osDisableInt(); - __Dom2SpeedParam.next = __osPiTable; - __osPiTable = &__Dom2SpeedParam; - __osDiskHandle = &__Dom2SpeedParam; - __osRestoreInt(saveMask); - return &__Dom2SpeedParam; -} diff --git a/lib/src/osPfsIsPlug.c b/lib/src/osPfsIsPlug.c deleted file mode 100644 index 5fc5b8fa..00000000 --- a/lib/src/osPfsIsPlug.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "PR/os_pi.h" -#include "libultra_internal.h" -#include "controller.h" -#include "macros.h" - -OSPifRam __osPfsPifRam; - -s32 osPfsIsPlug(OSMesgQueue *queue, u8 *pattern) { - s32 ret; - OSMesg dummy; - u8 bitpattern; - OSContStatus data[MAXCONTROLLERS]; - int channel; - u8 bits; - int crc_error_cnt; - ret = 0; - bits = 0; - crc_error_cnt = 3; - __osSiGetAccess(); - while (TRUE) { - __osPfsRequestData(CONT_CMD_REQUEST_STATUS); - ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); - osRecvMesg(queue, &dummy, OS_MESG_BLOCK); - ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); - osRecvMesg(queue, &dummy, OS_MESG_BLOCK); - __osPfsGetInitData(&bitpattern, data); - for (channel = 0; channel < __osMaxControllers; channel++) { - if ((data[channel].status & CONT_ADDR_CRC_ER) == 0) { - crc_error_cnt--; - break; - } - } - if (__osMaxControllers == channel) { - crc_error_cnt = 0; - } - if (crc_error_cnt < 1) { - for (channel = 0; channel < __osMaxControllers; channel++) { - if (data[channel].errnum == 0 && (data[channel].status & CONT_CARD_ON) != 0) { - bits |= 1 << channel; - } - } - __osSiRelAccess(); - *pattern = bits; - return ret; - } - } -} - -void __osPfsRequestData(u8 cmd) { - u8 *ptr; - __OSContRequesFormat requestformat; - int i; - - __osContLastCmd = cmd; - - for (i = 0; i < ARRAY_COUNT(__osPfsPifRam.ramarray) + 1; i++) { // also clear pifstatus - __osPfsPifRam.ramarray[i] = 0; - } - - __osPfsPifRam.pifstatus = CONT_CMD_EXE; - - ptr = (u8 *)&__osPfsPifRam; - requestformat.dummy = CONT_CMD_NOP; - requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX; - requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; - requestformat.cmd = cmd; - requestformat.typeh = CONT_CMD_NOP; - requestformat.typel = CONT_CMD_NOP; - requestformat.status = CONT_CMD_NOP; - requestformat.dummy1 = CONT_CMD_NOP; - for (i = 0; i < __osMaxControllers; i++) { - *(__OSContRequesFormat *)ptr = requestformat; - ptr += sizeof(__OSContRequesFormat); - } - *ptr = CONT_CMD_END; -} - -void __osPfsGetInitData(u8 *pattern, OSContStatus *data) { - u8 *ptr; - __OSContRequesFormat requestformat; - int i; - u8 bits; - bits = 0; - ptr = (u8 *)&__osPfsPifRam; - for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(__OSContRequesFormat)) { - requestformat = *(__OSContRequesFormat *)ptr; - data->errnum = CHNL_ERR(requestformat); - if (data->errnum == 0) { - data->type = (requestformat.typel << 8) | (requestformat.typeh); - data->status = requestformat.status; - bits |= 1 << i; - } - data++; - } - *pattern = bits; -} diff --git a/lib/src/osPiRawReadIo.c b/lib/src/osPiRawReadIo.c deleted file mode 100644 index a212d7a8..00000000 --- a/lib/src/osPiRawReadIo.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include "piint.h" - -s32 osPiRawReadIo(u32 devAddr, u32 *data) { - register u32 status; - - WAIT_ON_IO_BUSY(status); - *data = IO_READ(osRomBase | devAddr); - return 0; -} diff --git a/lib/src/osPiStartDma.c b/lib/src/osPiStartDma.c deleted file mode 100644 index 0a07d530..00000000 --- a/lib/src/osPiStartDma.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "libultra_internal.h" -#include "piint.h" - -s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, - size_t nbytes, OSMesgQueue *mq) { - register s32 result; - register OSMesgQueue *cmdQueue; - if (!__osPiDevMgr.active) { - return -1; - } - - // TODO: name magic constants - if (direction == OS_READ) { - mb->hdr.type = 11; - } else { - mb->hdr.type = 12; - } - - mb->hdr.pri = priority; - mb->hdr.retQueue = mq; - mb->dramAddr = vAddr; - mb->devAddr = devAddr; - mb->size = nbytes; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - mb->piHandle = NULL; -#endif - - if (priority == OS_MESG_PRI_HIGH) { - cmdQueue = osPiGetCmdQueue(); - result = osJamMesg(cmdQueue, mb, OS_MESG_NOBLOCK); - } else { - cmdQueue = osPiGetCmdQueue(); - result = osSendMesg(cmdQueue, mb, OS_MESG_NOBLOCK); - } - return result; -} diff --git a/lib/src/osSendMesg.c b/lib/src/osSendMesg.c deleted file mode 100644 index 596ca729..00000000 --- a/lib/src/osSendMesg.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "libultra_internal.h" - -s32 osSendMesg(OSMesgQueue *mq, OSMesg msg, s32 flag) { - register u32 int_disabled; - register s32 index; - int_disabled = __osDisableInt(); - - while (MQ_IS_FULL(mq)) { - if (flag == OS_MESG_BLOCK) { - __osRunningThread->state = 8; - __osEnqueueAndYield(&mq->fullqueue); - } else { - __osRestoreInt(int_disabled); - return -1; - } - } - - index = (mq->first + mq->validCount) % mq->msgCount; - mq->msg[index] = msg; - mq->validCount++; - - if (mq->mtqueue->next != NULL) { - osStartThread(__osPopThread(&mq->mtqueue)); - } - - __osRestoreInt(int_disabled); - return 0; -} diff --git a/lib/src/osSetEventMesg.c b/lib/src/osSetEventMesg.c deleted file mode 100644 index 3c50487a..00000000 --- a/lib/src/osSetEventMesg.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "libultra_internal.h" -#include "osint.h" - -__OSEventState __osEventStateTab[OS_NUM_EVENTS]; - -#ifdef VERSION_CN -u32 __osPreNMI = 0; -#endif - -void osSetEventMesg(OSEvent e, OSMesgQueue *mq, OSMesg msg) { - register u32 int_disabled; - __OSEventState *msgs; - int_disabled = __osDisableInt(); - - msgs = __osEventStateTab + e; - msgs->messageQueue = mq; - msgs->message = msg; - -#ifdef VERSION_CN - if (e == OS_EVENT_PRENMI) { - if (__osShutdown && !__osPreNMI) { - osSendMesg(mq, msg, OS_MESG_NOBLOCK); - } - - __osPreNMI = TRUE; - } -#endif - - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osSetThreadPri.c b/lib/src/osSetThreadPri.c deleted file mode 100644 index 84a9a4c1..00000000 --- a/lib/src/osSetThreadPri.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "libultra_internal.h" - -void osSetThreadPri(OSThread *thread, OSPri pri) { - register u32 int_disabled = __osDisableInt(); - if (thread == NULL) { - thread = __osRunningThread; - } - - if (thread->priority != pri) { - thread->priority = pri; - if (thread != __osRunningThread) { - if (thread->state != OS_STATE_STOPPED) { - __osDequeueThread(thread->queue, thread); - __osEnqueueThread(thread->queue, thread); - } - } - if (__osRunningThread->priority < __osRunQueue->priority) { - __osRunningThread->state = OS_STATE_RUNNABLE; - __osEnqueueAndYield(&__osRunQueue); - } - } - - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osSetTime.c b/lib/src/osSetTime.c deleted file mode 100644 index cad09ab2..00000000 --- a/lib/src/osSetTime.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libultra_internal.h" - -extern OSTime __osCurrentTime; - -void osSetTime(OSTime time) { - __osCurrentTime = time; -} diff --git a/lib/src/osSetTimer.c b/lib/src/osSetTimer.c deleted file mode 100644 index 54dcc3aa..00000000 --- a/lib/src/osSetTimer.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "libultra_internal.h" -#include "osint.h" - -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" - -u32 osSetTimer(OSTimer *timer, OSTime countdown, OSTime interval, OSMesgQueue *mq, OSMesg msg) { - OSTime time; -#ifdef VERSION_CN - OSTimer *next; - u32 count; - u32 remaining; - u32 prevInt; -#endif - - timer->next = NULL; - timer->prev = NULL; - timer->interval = interval; - timer->remaining = countdown != 0 ? countdown : interval; - timer->mq = mq; - timer->msg = msg; - -#ifdef VERSION_CN - prevInt = __osDisableInt(); - if (__osTimerList->next == __osTimerList) { - } else { - next = __osTimerList->next; - count = osGetCount(); - remaining = count - __osTimerCounter; - - if (remaining < next->remaining) { - next->remaining -= remaining; - } else { - next->remaining = 1; - } - } - - time = __osInsertTimer(timer); - __osSetTimerIntr(__osTimerList->next->remaining); - - __osRestoreInt(prevInt); -#else - time = __osInsertTimer(timer); - if (__osTimerList->next == timer) { - __osSetTimerIntr(time); - } -#endif - - return 0; -} diff --git a/lib/src/osSpTaskLoadGo.c b/lib/src/osSpTaskLoadGo.c deleted file mode 100644 index 6adb6cf9..00000000 --- a/lib/src/osSpTaskLoadGo.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" -#include - -#define _osVirtualToPhysical(ptr) \ - if (ptr != NULL) { \ - ptr = (void *) osVirtualToPhysical(ptr); \ - } - -FORCE_BSS OSTask tmpTask; - -OSTask *_VirtualToPhysicalTask(OSTask *task) { - OSTask *physicalTask; - physicalTask = &tmpTask; - bcopy(task, physicalTask, sizeof(OSTask)); - _osVirtualToPhysical(physicalTask->t.ucode); - _osVirtualToPhysical(physicalTask->t.ucode_data); - _osVirtualToPhysical(physicalTask->t.dram_stack); - _osVirtualToPhysical(physicalTask->t.output_buff); - _osVirtualToPhysical(physicalTask->t.output_buff_size); - _osVirtualToPhysical(physicalTask->t.data_ptr); - _osVirtualToPhysical(physicalTask->t.yield_data_ptr); - return physicalTask; -} - -void osSpTaskLoad(OSTask *task) { - OSTask *physicalTask; - physicalTask = _VirtualToPhysicalTask(task); - if (physicalTask->t.flags & M_TASK_FLAG0) { - physicalTask->t.ucode_data = physicalTask->t.yield_data_ptr; - physicalTask->t.ucode_data_size = physicalTask->t.yield_data_size; - task->t.flags &= ~M_TASK_FLAG0; -#if defined(VERSION_SH) || defined(VERSION_CN) - if (physicalTask->t.flags & M_TASK_FLAG2) { - physicalTask->t.ucode = (u64 *) IO_READ((uintptr_t)task->t.yield_data_ptr + 0xBFC); - } -#endif - } - osWritebackDCache(physicalTask, sizeof(OSTask)); - __osSpSetStatus(SPSTATUS_CLEAR_SIGNAL0 | SPSTATUS_CLEAR_SIGNAL1 | SPSTATUS_CLEAR_SIGNAL2 - | SPSTATUS_SET_INTR_ON_BREAK); - while (__osSpSetPc((void *) SP_IMEM_START) == -1) { - ; - } - while (__osSpRawStartDma(1, (void *) (SP_IMEM_START - sizeof(*physicalTask)), physicalTask, - sizeof(OSTask)) - == -1) { - ; - } - while (__osSpDeviceBusy()) { - ; - } - while (__osSpRawStartDma(1, (void *) SP_IMEM_START, physicalTask->t.ucode_boot, - physicalTask->t.ucode_boot_size) - == -1) { - ; - } -} - -void osSpTaskStartGo(UNUSED OSTask *task) { - while (__osSpDeviceBusy()) { - ; - } - __osSpSetStatus(SPSTATUS_SET_INTR_ON_BREAK | SPSTATUS_CLEAR_SSTEP | SPSTATUS_CLEAR_BROKE - | SPSTATUS_CLEAR_HALT); -} diff --git a/lib/src/osSpTaskYield.c b/lib/src/osSpTaskYield.c deleted file mode 100644 index 92546a8f..00000000 --- a/lib/src/osSpTaskYield.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "libultra_internal.h" - -void osSpTaskYield(void) { - __osSpSetStatus(SPSTATUS_SET_SIGNAL0); -} diff --git a/lib/src/osSpTaskYielded.c b/lib/src/osSpTaskYielded.c deleted file mode 100644 index 67616950..00000000 --- a/lib/src/osSpTaskYielded.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "libultra_internal.h" - -OSYieldResult osSpTaskYielded(OSTask *task) { - s32 status; - u32 int_disabledult; - status = __osSpGetStatus(); - int_disabledult = (status & SPSTATUS_SIGNAL1_SET) != 0 ? 1 : 0; - if (status & SPSTATUS_SIGNAL0_SET) { - task->t.flags |= int_disabledult; - task->t.flags &= ~(M_TASK_FLAG1); - } - return int_disabledult; -} diff --git a/lib/src/osStartThread.c b/lib/src/osStartThread.c deleted file mode 100644 index af51060e..00000000 --- a/lib/src/osStartThread.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "libultra_internal.h" - -void osStartThread(OSThread *thread) { - register u32 int_disabled; - int_disabled = __osDisableInt(); - - switch (thread->state) { - case OS_STATE_WAITING: - thread->state = OS_STATE_RUNNABLE; - __osEnqueueThread(&__osRunQueue, thread); - break; - case OS_STATE_STOPPED: - if (thread->queue == NULL || thread->queue == &__osRunQueue) { - thread->state = OS_STATE_RUNNABLE; - - __osEnqueueThread(&__osRunQueue, thread); - } else { - thread->state = OS_STATE_WAITING; - __osEnqueueThread(thread->queue, thread); - __osEnqueueThread(&__osRunQueue, __osPopThread(thread->queue)); - } - break; - } - - if (__osRunningThread == NULL) { - __osDispatchThread(); - } else { - if (__osRunningThread->priority < __osRunQueue->priority) { - __osRunningThread->state = OS_STATE_RUNNABLE; - __osEnqueueAndYield(&__osRunQueue); - } - } - - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osSyncPrintf.c b/lib/src/osSyncPrintf.c deleted file mode 100644 index f9a89861..00000000 --- a/lib/src/osSyncPrintf.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "macros.h" - -#ifdef VERSION_CN - -// ? -void func_cn_80304B30(void) {} - -void osSyncPrintf(UNUSED const char *fmt, ...) {} -void osAsyncPrintf(UNUSED const char *fmt, ...) {} - -#endif diff --git a/lib/src/osViBlack.c b/lib/src/osViBlack.c deleted file mode 100644 index 277dfedb..00000000 --- a/lib/src/osViBlack.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "libultra_internal.h" - -extern OSViContext *__osViNext; - -// TODO: name magic constants -void osViBlack(u8 active) { - register u32 int_disabled = __osDisableInt(); - if (active) { - __osViNext->unk00 |= 0x20; - } else { - __osViNext->unk00 &= ~0x20; - } - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osViData.c b/lib/src/osViData.c deleted file mode 100644 index 42923b54..00000000 --- a/lib/src/osViData.c +++ /dev/null @@ -1,217 +0,0 @@ -#include "libultra_internal.h" - -#ifdef VERSION_CN - -OSViMode osViModeNtscLan1 = { - /*type*/ 2, - /*comRegs*/ - { /*ctrl*/ 4382, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } -}; - -OSViMode osViModePalLan1 = { - /*type*/ 16, - /*comRegs*/ - { /*ctrl*/ 4382, - /*width*/ 320, - /*burst*/ 72621626, - /*vSync*/ 625, - /*hSync*/ 1510505, - /*leap*/ 208604269, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } -}; - -OSViMode osViModeMpalLan1 = { - /*type*/ 30, - /*comRegs*/ - { /*ctrl*/ 4382, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } -}; - -#elif defined(VERSION_EU) || defined(VERSION_SH) - -OSViMode osViModePalLan1 = { - /*type*/ 16, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, -#ifdef VERSION_EU - /*burst*/ 67380026, -#else - /*burst*/ 72621626, -#endif - /*vSync*/ 625, -#ifdef VERSION_EU - /*hSync*/ 1379433, - /*leap*/ 208604270, -#else - /*hSync*/ 1510505, - /*leap*/ 208604269, -#endif - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } -}; - -OSViMode osViModeMpalLan1 = { - /*type*/ 30, //osViModePalLan1 - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } -}; - -OSViMode osViModeNtscLan1 = { - /*type*/ 2, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } -}; - -#else - -OSViMode osViModePalLan1 = { - /*type*/ 2, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } -}; - -OSViMode osViModeMpalLan1 = { - /*type*/ 16, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 625, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } -}; -#endif diff --git a/lib/src/osViSetEvent.c b/lib/src/osViSetEvent.c deleted file mode 100644 index 6969ec8f..00000000 --- a/lib/src/osViSetEvent.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "libultra_internal.h" - -extern OSViContext *__osViNext; - -void osViSetEvent(OSMesgQueue *mq, OSMesg msg, u32 retraceCount) { - register u32 int_disabled = __osDisableInt(); - (__osViNext)->mq = mq; - (__osViNext)->msg = msg; - (__osViNext)->retraceCount = retraceCount; - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osViSetMode.c b/lib/src/osViSetMode.c deleted file mode 100644 index 1820f257..00000000 --- a/lib/src/osViSetMode.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "libultra_internal.h" - -extern u32 __osBbIsBb; - -extern OSViContext *__osViNext; - -void osViSetMode(OSViMode *mode) { - register u32 int_disabled = __osDisableInt(); -#ifdef VERSION_CN - if (__osBbIsBb != 0) { - mode->comRegs.ctrl &= ~0x2000; - } -#endif - __osViNext->modep = mode; - __osViNext->unk00 = 1; - __osViNext->features = __osViNext->modep->comRegs.ctrl; - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osViSetSpecialFeatures.c b/lib/src/osViSetSpecialFeatures.c deleted file mode 100644 index c1bf52b6..00000000 --- a/lib/src/osViSetSpecialFeatures.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "libultra_internal.h" - -extern OSViContext *__osViNext; - -void osViSetSpecialFeatures(u32 func) { - register u32 int_disabled = __osDisableInt(); - if (func & OS_VI_GAMMA_ON) { - __osViNext->features |= OS_VI_GAMMA; - } - if (func & OS_VI_GAMMA_OFF) { - __osViNext->features &= ~OS_VI_GAMMA; - } - if (func & OS_VI_GAMMA_DITHER_ON) { - __osViNext->features |= OS_VI_GAMMA_DITHER; - } - if (func & OS_VI_GAMMA_DITHER_OFF) { - __osViNext->features &= ~OS_VI_GAMMA_DITHER; - } - if (func & OS_VI_DIVOT_ON) { - __osViNext->features |= OS_VI_DIVOT; - } - if (func & OS_VI_DIVOT_OFF) { - __osViNext->features &= ~OS_VI_DIVOT; - } - if (func & OS_VI_DITHER_FILTER_ON) { - __osViNext->features |= OS_VI_DITHER_FILTER; - __osViNext->features &= ~(OS_VI_UNK200 | OS_VI_UNK100); - } - if (func & OS_VI_DITHER_FILTER_OFF) { - __osViNext->features &= ~OS_VI_DITHER_FILTER; - __osViNext->features |= __osViNext->modep->comRegs.ctrl & (OS_VI_UNK200 | OS_VI_UNK100); - } - __osViNext->unk00 |= 8; - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osViSwapBuffer.c b/lib/src/osViSwapBuffer.c deleted file mode 100644 index c2cb1d50..00000000 --- a/lib/src/osViSwapBuffer.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "libultra_internal.h" - -extern OSViContext *__osViNext; - -void osViSwapBuffer(void *vaddr) { - u32 int_disabled = __osDisableInt(); - __osViNext->buffer = vaddr; - __osViNext->unk00 |= 0x10; // TODO: figure out what this flag means - __osRestoreInt(int_disabled); -} diff --git a/lib/src/osViTable.c b/lib/src/osViTable.c deleted file mode 100644 index 553f0e9f..00000000 --- a/lib/src/osViTable.c +++ /dev/null @@ -1,996 +0,0 @@ -#include "libultra_internal.h" - -#if defined(VERSION_SH) || defined(VERSION_CN) -#define COMMON_BURST 72621626 -#define COMMON_HSYNC 1510505 -#define COMMON_LEAP 208604269 -#else -#define COMMON_BURST 67380026 -#define COMMON_HSYNC 1379433 -#define COMMON_LEAP 208604270 -#endif - -#ifdef VERSION_CN -#define CN_SUB 8192 -#else -#define CN_SUB 0 -#endif - -OSViMode osViModeTable[] = { - /*osViModeNtscLpn1*/ - { /*type*/ 0, - /*comRegs*/ - { /*ctrl*/ 12814 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLpf1*/ - { /*type*/ 1, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLan1*/ - { /*type*/ 2, - /*comRegs*/ - { /*ctrl*/ 12574 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLaf1*/ - { /*type*/ 3, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLpn2*/ - { /*type*/ 4, - /*comRegs*/ - { /*ctrl*/ 13071 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLpf2*/ - { /*type*/ 5, - /*comRegs*/ - { /*ctrl*/ 12879 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLan2*/ - { /*type*/ 6, - /*comRegs*/ - { /*ctrl*/ 12319 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLaf2*/ - { /*type*/ 7, - /*comRegs*/ - { /*ctrl*/ 12383 - CN_SUB, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpn1*/ - { /*type*/ 8, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 1280, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpf1*/ - { /*type*/ 9, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 640, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHan1*/ - { /*type*/ 10, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 1280, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHaf1*/ - { /*type*/ 11, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 640, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpn2*/ - { /*type*/ 12, - /*comRegs*/ - { /*ctrl*/ 13135 - CN_SUB, - /*width*/ 1280, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpf2*/ - { /*type*/ 13, - /*comRegs*/ - { /*ctrl*/ 12879 - CN_SUB, - /*width*/ 640, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - -#ifndef VERSION_US - /*osViModePalLpn1*/ - { /*type*/ 14, - /*comRegs*/ - { /*ctrl*/ 12814 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 625, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLpf1*/ - { /*type*/ 15, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalLan1*/ - { /*type*/ 16, - /*comRegs*/ - { /*ctrl*/ 12574 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 625, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLaf1*/ - { /*type*/ 17, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalLpn2*/ - { /*type*/ 18, - /*comRegs*/ - { /*ctrl*/ 13071 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 625, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLpf2*/ - { /*type*/ 19, - /*comRegs*/ - { /*ctrl*/ 12879 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalLan2*/ - { /*type*/ 20, - /*comRegs*/ - { /*ctrl*/ 12319 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 625, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLaf2*/ - { /*type*/ 21, - /*comRegs*/ - { /*ctrl*/ 12383 - CN_SUB, - /*width*/ 320, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpn1*/ - { /*type*/ 22, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 1280, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpf1*/ - { /*type*/ 23, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 640, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHan1*/ - { /*type*/ 24, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 1280, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHaf1*/ - { /*type*/ 25, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 640, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpn2*/ - { /*type*/ 26, - /*comRegs*/ - { /*ctrl*/ 13135 - CN_SUB, - /*width*/ 1280, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpf2*/ - { /*type*/ 27, - /*comRegs*/ - { /*ctrl*/ 12879 - CN_SUB, - /*width*/ 640, - /*burst*/ COMMON_BURST, - /*vSync*/ 624, - /*hSync*/ COMMON_HSYNC, - /*leap*/ COMMON_LEAP, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 33556480, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, -#endif - -#ifndef VERSION_JP - /*osViModePalLpn1*/ - { /*type*/ 28, - /*comRegs*/ - { /*ctrl*/ 12814 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLpf1*/ - { /*type*/ 29, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLan1*/ - { /*type*/ 30, - /*comRegs*/ - { /*ctrl*/ 12574 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLaf1*/ - { /*type*/ 31, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLpn2*/ - { /*type*/ 32, - /*comRegs*/ - { /*ctrl*/ 13071 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLpf2*/ - { /*type*/ 33, - /*comRegs*/ - { /*ctrl*/ 12879 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLan2*/ - { /*type*/ 34, - /*comRegs*/ - { /*ctrl*/ 12319 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLaf2*/ - { /*type*/ 35, - /*comRegs*/ - { /*ctrl*/ 12383 - CN_SUB, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpn1*/ - { /*type*/ 36, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 1280, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpf1*/ - { /*type*/ 37, - /*comRegs*/ - { /*ctrl*/ 12878 - CN_SUB, - /*width*/ 640, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHan1*/ - { /*type*/ 38, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 1280, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHaf1*/ - { /*type*/ 39, - /*comRegs*/ - { /*ctrl*/ 12382 - CN_SUB, - /*width*/ 640, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpn2*/ - { /*type*/ 40, - /*comRegs*/ - { /*ctrl*/ 13135 - CN_SUB, - /*width*/ 1280, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpf2*/ - { /*type*/ 41, - /*comRegs*/ - { /*ctrl*/ 12879 - CN_SUB, - /*width*/ 640, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } } -#endif -}; - -#ifdef VERSION_CN -s8 unk_cn_803191c0[] = {0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0E, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x71, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4E, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x1E, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x71, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x5E, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x0F, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x71, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4F, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x71, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x5F, 0x00, 0x00, 0x01, 0x40, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4E, 0x00, 0x00, 0x05, 0x00, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4E, 0x00, 0x00, 0x02, 0x80, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x5E, 0x00, 0x00, 0x05, 0x00, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x5E, 0x00, 0x00, 0x02, 0x80, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4F, 0x00, 0x00, 0x05, 0x00, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x4F, 0x00, 0x00, 0x02, 0x80, 0x04, 0x54, 0x1E, 0x3A, 0x00, 0x00, 0x02, 0x70, 0x00, 0x17, 0x0C, 0x69, 0x0C, 0x6F, 0x0C, 0x6D, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x2D, 0x02, 0x67, 0x00, 0x09, 0x02, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x2F, 0x02, 0x69, 0x00, 0x0D, 0x02, 0x69, 0x00, 0x00, 0x00, 0x02}; -#endif diff --git a/lib/src/pfsgetstatus.c b/lib/src/pfsgetstatus.c deleted file mode 100644 index 520cb345..00000000 --- a/lib/src/pfsgetstatus.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "libultra_internal.h" -#include "controller.h" - -s32 __osPfsGetStatus(OSMesgQueue *queue, s32 channel) { - s32 ret = 0; - OSMesg dummy; - u8 pattern; - OSContStatus data[4]; - - __osPfsRequestData(CONT_CMD_REQUEST_STATUS); - ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); - osRecvMesg(queue, &dummy, OS_MESG_BLOCK); - ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); - osRecvMesg(queue, &dummy, OS_MESG_BLOCK); - __osPfsGetInitData(&pattern, data); - if (data[channel].status & CONT_CARD_ON && data[channel].status & CONT_CARD_PULL) { - return PFS_ERR_NEW_PACK; - } - if (data[channel].errnum || !(data[channel].status & CONT_CARD_ON)) { - return PFS_ERR_NOPACK; - } - if (data[channel].status & CONT_ADDR_CRC_ER) { - return PFS_ERR_CONTRFAIL; - } - return ret; -} diff --git a/lib/src/printf.h b/lib/src/printf.h deleted file mode 100644 index a4222930..00000000 --- a/lib/src/printf.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _PRINTF_H_ -#define _PRINTF_H_ -#include - -#ifdef VERSION_CN -typedef char fmt_type; -#else -typedef u8 fmt_type; -#endif - -typedef struct -{ - union { - /* 00 */ s64 s64; - u64 u64; - f64 f64; - u32 u32; - u16 u16; - } value; - /* 08 */ char *buff; - /* 0c */ s32 part1_len; - /* 10 */ s32 num_leading_zeros; - /* 14 */ s32 part2_len; - /* 18 */ s32 num_mid_zeros; - /* 1c */ s32 part3_len; - /* 20 */ s32 num_trailing_zeros; - /* 24 */ s32 precision; - /* 28 */ s32 width; - /* 2c */ u32 size; - /* 30 */ u32 flags; - /* 34 */ fmt_type length; -} printf_struct; - -#define FLAGS_SPACE 1 -#define FLAGS_PLUS 2 -#define FLAGS_MINUS 4 -#define FLAGS_HASH 8 -#define FLAGS_ZERO 16 -s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args); -void _Litob(printf_struct *args, fmt_type type); -void _Ldtob(printf_struct *args, fmt_type type); -#endif diff --git a/lib/src/sprintf.c b/lib/src/sprintf.c deleted file mode 100644 index 8450fbc5..00000000 --- a/lib/src/sprintf.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include "libultra_internal.h" -#include "printf.h" -#include - -char *proutSprintf(char *dst, const char *src, size_t count); - -int sprintf(char *dst, const char *fmt, ...) { - s32 written; - va_list args; - va_start(args, fmt); - written = _Printf(proutSprintf, dst, fmt, args); - if (written >= 0) { - dst[written] = 0; - } - return written; -} - -char *proutSprintf(char *dst, const char *src, size_t count) { - return (char *) memcpy((u8 *) dst, (u8 *) src, count) + count; -} diff --git a/lib/src/string.c b/lib/src/string.c deleted file mode 100644 index fafe7fa9..00000000 --- a/lib/src/string.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "libultra_internal.h" -#include - -#ifdef VERSION_CN - -char *strchr(const char *str, s32 ch) { - char c = ch; - while (*str != c) { - if (*str == 0) { - return NULL; - } - str++; - } - return (char *) str; -} - -size_t strlen(const char *str) { - const char *ptr = str; - while (*ptr) { - ptr++; - } - return ptr - str; -} - -#endif - -void *memcpy(void *dst, const void *src, size_t size) { - u8 *_dst = dst; - const u8 *_src = src; - while (size > 0) { - *_dst++ = *_src++; - size--; - } - return dst; -} - -#ifndef VERSION_CN - -size_t strlen(const char *str) { - const u8 *ptr = (const u8 *) str; - while (*ptr) { - ptr++; - } - return (const char *) ptr - str; -} - -char *strchr(const char *str, s32 ch) { - u8 c = ch; - while (*(u8 *)str != c) { - if (*(u8 *)str == 0) { - return NULL; - } - str++; - } - return (char *) str; -} - -#endif diff --git a/lib/ultra/D.inc b/lib/ultra/D.inc new file mode 100644 index 00000000..d06de4be --- /dev/null +++ b/lib/ultra/D.inc @@ -0,0 +1,115 @@ + BUILD_DIR/libultra.a:parameters.o(.SECTION); + BUILD_DIR/libultra.a:settime.o(.SECTION); + BUILD_DIR/libultra.a:maptlb.o(.SECTION); + BUILD_DIR/libultra.a:unmaptlball.o(.SECTION); + BUILD_DIR/libultra.a:sprintf.o(.SECTION); + BUILD_DIR/libultra.a:createmesgqueue.o(.SECTION); + BUILD_DIR/libultra.a:seteventmesg.o(.SECTION); + BUILD_DIR/libultra.a:visetevent.o(.SECTION); + BUILD_DIR/libultra.a:createthread.o(.SECTION); + BUILD_DIR/libultra.a:recvmesg.o(.SECTION); + BUILD_DIR/libultra.a:sptask.o(.SECTION); + BUILD_DIR/libultra.a:sptaskyield.o(.SECTION); + BUILD_DIR/libultra.a:sendmesg.o(.SECTION); + BUILD_DIR/libultra.a:sptaskyielded.o(.SECTION); + BUILD_DIR/libultra.a:startthread.o(.SECTION); + BUILD_DIR/libultra.a:writebackdcacheall.o(.SECTION); + BUILD_DIR/libultra.a:vitbl.o(.SECTION); + BUILD_DIR/libultra.a:vimgr.o(.SECTION); + BUILD_DIR/libultra.a:visetmode.o(.SECTION); + BUILD_DIR/libultra.a:viblack.o(.SECTION); + BUILD_DIR/libultra.a:visetspecial.o(.SECTION); + BUILD_DIR/libultra.a:pimgr.o(.SECTION); + BUILD_DIR/libultra.a:setthreadpri.o(.SECTION); + BUILD_DIR/libultra.a:initialize.o(.SECTION); + BUILD_DIR/libultra.a:viswapbuf.o(.SECTION); + BUILD_DIR/libultra.a:sqrtf.o(.SECTION); + BUILD_DIR/libultra.a:contreaddata.o(.SECTION); + BUILD_DIR/libultra.a:controller.o(.SECTION); + BUILD_DIR/libultra.a:conteepprobe.o(.SECTION); + BUILD_DIR/libultra.a:ll.o(.SECTION); + BUILD_DIR/libultra.a:invaldcache.o(.SECTION); + BUILD_DIR/libultra.a:pidma.o(.SECTION); + BUILD_DIR/libultra.a:bzero.o(.SECTION); + BUILD_DIR/libultra.a:invalicache.o(.SECTION); + BUILD_DIR/libultra.a:conteeplongread.o(.SECTION); + BUILD_DIR/libultra.a:conteeplongwrite.o(.SECTION); + BUILD_DIR/libultra.a:bcopy.o(.SECTION); + BUILD_DIR/libultra.a:ortho.o(.SECTION); + BUILD_DIR/libultra.a:perspective.o(.SECTION); + BUILD_DIR/libultra.a:gettime.o(.SECTION); + BUILD_DIR/libultra.a:llcvt.o(.SECTION); + BUILD_DIR/libultra.a:cosf.o(.SECTION); + BUILD_DIR/libultra.a:sinf.o(.SECTION); + BUILD_DIR/libultra.a:translate.o(.SECTION); + BUILD_DIR/libultra.a:rotate.o(.SECTION); + BUILD_DIR/libultra.a:scale.o(.SECTION); + BUILD_DIR/libultra.a:aisetfreq.o(.SECTION); + BUILD_DIR/libultra.a:bnkf.o(.SECTION); + BUILD_DIR/libultra.a:writebackdcache.o(.SECTION); + BUILD_DIR/libultra.a:aigetlen.o(.SECTION); + BUILD_DIR/libultra.a:aisetnextbuf.o(.SECTION); + BUILD_DIR/libultra.a:timerintr.o(.SECTION); + BUILD_DIR/libultra.a:xprintf.o(.SECTION); + BUILD_DIR/libultra.a:string.o(.SECTION); + BUILD_DIR/libultra.a:thread.o(.SECTION); + BUILD_DIR/libultra.a:interrupt.o(.SECTION); + BUILD_DIR/libultra.a:vi.o(.SECTION); + BUILD_DIR/libultra.a:exceptasm.o(.SECTION); + BUILD_DIR/libultra.a:virtualtophysical.o(.SECTION); + BUILD_DIR/libultra.a:spsetstat.o(.SECTION); + BUILD_DIR/libultra.a:spsetpc.o(.SECTION); + BUILD_DIR/libultra.a:sprawdma.o(.SECTION); + BUILD_DIR/libultra.a:sp.o(.SECTION); + BUILD_DIR/libultra.a:spgetstat.o(.SECTION); + BUILD_DIR/libultra.a:getthreadpri.o(.SECTION); + BUILD_DIR/libultra.a:vigetcurrcontext.o(.SECTION); + BUILD_DIR/libultra.a:viswapcontext.o(.SECTION); + BUILD_DIR/libultra.a:getcount.o(.SECTION); + BUILD_DIR/libultra.a:piacs.o(.SECTION); + BUILD_DIR/libultra.a:pirawdma.o(.SECTION); + BUILD_DIR/libultra.a:devmgr.o(.SECTION); + BUILD_DIR/libultra.a:setsr.o(.SECTION); + BUILD_DIR/libultra.a:getsr.o(.SECTION); + BUILD_DIR/libultra.a:setfpccsr.o(.SECTION); + BUILD_DIR/libultra.a:sirawread.o(.SECTION); + BUILD_DIR/libultra.a:sirawwrite.o(.SECTION); + BUILD_DIR/libultra.a:maptlbrdb.o(.SECTION); + BUILD_DIR/libultra.a:pirawread.o(.SECTION); +#if defined(JP_PADDING_TEXT) && !defined(NON_MATCHING) + . += 0x40; /* Not a 2.0D diff, probably a compiler thing */ +#endif + BUILD_DIR/libultra.a:siacs.o(.SECTION); + BUILD_DIR/libultra.a:sirawdma.o(.SECTION); + BUILD_DIR/libultra.a:settimer.o(.SECTION); + BUILD_DIR/libultra.a:conteepwrite.o(.SECTION); + BUILD_DIR/libultra.a:jammesg.o(.SECTION); + BUILD_DIR/libultra.a:pigetcmdq.o(.SECTION); + BUILD_DIR/libultra.a:conteepread.o(.SECTION); + BUILD_DIR/libultra.a:mtxutil.o(.SECTION); + BUILD_DIR/libultra.a:normalize.o(.SECTION); + BUILD_DIR/libultra.a:ai.o(.SECTION); + BUILD_DIR/libultra.a:setcompare.o(.SECTION); + BUILD_DIR/libultra.a:libm_vals.o(.SECTION); + BUILD_DIR/libultra.a:xlitob.o(.SECTION); + BUILD_DIR/libultra.a:xldtob.o(.SECTION); + BUILD_DIR/libultra.a:vimodentsclan1.o(.SECTION); + BUILD_DIR/libultra.a:vimodepallan1.o(.SECTION); + BUILD_DIR/libultra.a:kdebugserver.o(.SECTION); + BUILD_DIR/libultra.a:syncputchars.o(.SECTION); + BUILD_DIR/libultra.a:setintmask.o(.SECTION); + BUILD_DIR/libultra.a:destroythread.o(.SECTION); + BUILD_DIR/libultra.a:probetlb.o(.SECTION); + BUILD_DIR/libultra.a:si.o(.SECTION); + BUILD_DIR/libultra.a:ldiv.o(.SECTION); + BUILD_DIR/libultra.a:getcause.o(.SECTION); + BUILD_DIR/libultra.a:atomic.o(.SECTION); + BUILD_DIR/libultra.a:lookatref.o(.SECTION); /* Fast3DEX2 only */ +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:pfsgetstatus.o(.SECTION); + BUILD_DIR/libultra.a:motor.o(.SECTION); + BUILD_DIR/libultra.a:pfsisplug.o(.SECTION); + BUILD_DIR/libultra.a:crc.o(.SECTION); + BUILD_DIR/libultra.a:contramwrite.o(.SECTION); + BUILD_DIR/libultra.a:contramread.o(.SECTION); +#endif diff --git a/lib/ultra/F_I.inc b/lib/ultra/F_I.inc new file mode 100644 index 00000000..7ace54e8 --- /dev/null +++ b/lib/ultra/F_I.inc @@ -0,0 +1,155 @@ + BUILD_DIR/libultra.a:string.o(.SECTION); + BUILD_DIR/libultra.a:xprintf.o(.SECTION); + BUILD_DIR/libultra.a:ll.o(.SECTION); + BUILD_DIR/libultra.a:initialize.o(.SECTION); + BUILD_DIR/libultra.a:settime.o(.SECTION); + BUILD_DIR/libultra.a:gettime.o(.SECTION); + BUILD_DIR/libultra.a:writebackdcacheall.o(.SECTION); + BUILD_DIR/libultra.a:viblack.o(.SECTION); + BUILD_DIR/libultra.a:viswapbuf.o(.SECTION); + BUILD_DIR/libultra.a:getcurrfaultthread.o(.SECTION); + BUILD_DIR/libultra.a:seteventmesg.o(.SECTION); + BUILD_DIR/libultra.a:recvmesg.o(.SECTION); + BUILD_DIR/libultra.a:parameters.o(.SECTION); + BUILD_DIR/libultra.a:createmesgqueue.o(.SECTION); + BUILD_DIR/libultra.a:createthread.o(.SECTION); + BUILD_DIR/libultra.a:startthread.o(.SECTION); + BUILD_DIR/libultra.a:maptlb.o(.SECTION); + BUILD_DIR/libultra.a:unmaptlball.o(.SECTION); + BUILD_DIR/libultra.a:sprintf.o(.SECTION); + BUILD_DIR/libultra.a:syncprintf.o(.SECTION); + BUILD_DIR/libultra.a:visetevent.o(.SECTION); + BUILD_DIR/libultra.a:sptask.o(.SECTION); + BUILD_DIR/libultra.a:sptaskyield.o(.SECTION); + BUILD_DIR/libultra.a:sendmesg.o(.SECTION); + BUILD_DIR/libultra.a:sptaskyielded.o(.SECTION); + BUILD_DIR/libultra.a:vimgr.o(.SECTION); + BUILD_DIR/libultra.a:visetmode.o(.SECTION); + BUILD_DIR/libultra.a:visetspecial.o(.SECTION); + BUILD_DIR/libultra.a:vitbl.o(.SECTION); + BUILD_DIR/libultra.a:pimgr.o(.SECTION); + BUILD_DIR/libultra.a:setthreadpri.o(.SECTION); + BUILD_DIR/libultra.a:sqrtf.o(.SECTION); + BUILD_DIR/libultra.a:contreaddata.o(.SECTION); + BUILD_DIR/libultra.a:controller.o(.SECTION); + BUILD_DIR/libultra.a:conteepprobe.o(.SECTION); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:motor.o(.SECTION); +#endif + BUILD_DIR/libultra.a:invaldcache.o(.SECTION); + BUILD_DIR/libultra.a:pidma.o(.SECTION); + BUILD_DIR/libultra.a:bzero.o(.SECTION); + BUILD_DIR/libultra.a:invalicache.o(.SECTION); + BUILD_DIR/libultra.a:conteeplongread.o(.SECTION); + BUILD_DIR/libultra.a:conteeplongwrite.o(.SECTION); + BUILD_DIR/libultra.a:bcopy.o(.SECTION); + BUILD_DIR/libultra.a:ortho.o(.SECTION); + BUILD_DIR/libultra.a:perspective.o(.SECTION); + BUILD_DIR/libultra.a:llcvt.o(.SECTION); + BUILD_DIR/libultra.a:cosf.o(.SECTION); + BUILD_DIR/libultra.a:sinf.o(.SECTION); + BUILD_DIR/libultra.a:translate.o(.SECTION); + BUILD_DIR/libultra.a:rotate.o(.SECTION); + BUILD_DIR/libultra.a:scale.o(.SECTION); + BUILD_DIR/libultra.a:aisetfreq.o(.SECTION); + BUILD_DIR/libultra.a:cartrominit.o(.SECTION); + BUILD_DIR/libultra.a:epidma.o(.SECTION); + BUILD_DIR/libultra.a:bnkf.o(.SECTION); + BUILD_DIR/libultra.a:aigetlen.o(.SECTION); + BUILD_DIR/libultra.a:aisetnextbuf.o(.SECTION); +#if LIBULTRA_VERSION >= OS_VER_H + BUILD_DIR/libultra.a:getcount.o(.SECTION); + BUILD_DIR/libultra.a:interrupt.o(.SECTION); +#endif + BUILD_DIR/libultra.a:xlitob.o(.SECTION); + BUILD_DIR/libultra.a:xldtob.o(.SECTION); + BUILD_DIR/libultra.a:setsr.o(.SECTION); + BUILD_DIR/libultra.a:getsr.o(.SECTION); + BUILD_DIR/libultra.a:setfpccsr.o(.SECTION); + BUILD_DIR/libultra.a:sirawread.o(.SECTION); + BUILD_DIR/libultra.a:sirawwrite.o(.SECTION); + BUILD_DIR/libultra.a:exceptasm.o(.SECTION); + BUILD_DIR/libultra.a:writebackdcache.o(.SECTION); + BUILD_DIR/libultra.a:maptlbrdb.o(.SECTION); + BUILD_DIR/libultra.a:pirawread.o(.SECTION); + BUILD_DIR/libultra.a:sethwinterrupt.o(.SECTION); +#if LIBULTRA_VERSION <= OS_VER_F + BUILD_DIR/libultra.a:leointerrupt.o(.SECTION); +#endif + BUILD_DIR/libultra.a:timerintr.o(.SECTION); +#if LIBULTRA_VERSION <= OS_VER_F + BUILD_DIR/libultra.a:interrupt.o(.SECTION); + BUILD_DIR/libultra.a:getcount.o(.SECTION); +#endif + BUILD_DIR/libultra.a:vi.o(.SECTION); + BUILD_DIR/libultra.a:thread.o(.SECTION); + BUILD_DIR/libultra.a:virtualtophysical.o(.SECTION); + BUILD_DIR/libultra.a:spsetstat.o(.SECTION); + BUILD_DIR/libultra.a:spsetpc.o(.SECTION); + BUILD_DIR/libultra.a:sprawdma.o(.SECTION); + BUILD_DIR/libultra.a:sp.o(.SECTION); + BUILD_DIR/libultra.a:spgetstat.o(.SECTION); + BUILD_DIR/libultra.a:getthreadpri.o(.SECTION); + BUILD_DIR/libultra.a:vigetcurrcontext.o(.SECTION); + BUILD_DIR/libultra.a:viswapcontext.o(.SECTION); +#if LIBULTRA_VERSION >= OS_VER_H + BUILD_DIR/libultra.a:leodiskinit.o(.SECTION); +#endif + BUILD_DIR/libultra.a:piacs.o(.SECTION); + BUILD_DIR/libultra.a:pirawdma.o(.SECTION); + BUILD_DIR/libultra.a:epirawdma.o(.SECTION); + BUILD_DIR/libultra.a:devmgr.o(.SECTION); + BUILD_DIR/libultra.a:siacs.o(.SECTION); + BUILD_DIR/libultra.a:sirawdma.o(.SECTION); + BUILD_DIR/libultra.a:settimer.o(.SECTION); +#if ENABLE_RUMBLE && defined(SH_PFS_BSS) + BUILD_DIR/libultra.a:pfsisplug.o(.SECTION); +#endif + BUILD_DIR/libultra.a:conteepwrite.o(.SECTION); + BUILD_DIR/libultra.a:kdebugserver.o(.SECTION); + BUILD_DIR/libultra.a:vimodepallan1.o(.SECTION); + BUILD_DIR/libultra.a:vimodempallan1.o(.SECTION); + BUILD_DIR/libultra.a:vimodentsclan1.o(.SECTION); + BUILD_DIR/libultra.a:libm_vals.o(.SECTION); +#if ENABLE_RUMBLE +#ifndef SH_PFS_BSS + BUILD_DIR/libultra.a:pfsisplug.o(.SECTION); +#endif + BUILD_DIR/libultra.a:crc.o(.SECTION); + BUILD_DIR/libultra.a:contramwrite.o(.SECTION); + BUILD_DIR/libultra.a:contramread.o(.SECTION); +#endif + BUILD_DIR/libultra.a:jammesg.o(.SECTION); + BUILD_DIR/libultra.a:pigetcmdq.o(.SECTION); + BUILD_DIR/libultra.a:conteepread.o(.SECTION); + BUILD_DIR/libultra.a:mtxutil.o(.SECTION); + BUILD_DIR/libultra.a:normalize.o(.SECTION); + BUILD_DIR/libultra.a:ai.o(.SECTION); + BUILD_DIR/libultra.a:ldiv.o(.SECTION); + BUILD_DIR/libultra.a:si.o(.SECTION); +#if LIBULTRA_VERSION >= OS_VER_H + BUILD_DIR/libultra.a:leointerrupt.o(.SECTION); +#endif + BUILD_DIR/libultra.a:setintmask.o(.SECTION); + BUILD_DIR/libultra.a:destroythread.o(.SECTION); +#if LIBULTRA_VERSION <= OS_VER_F + BUILD_DIR/libultra.a:leodiskinit.o(.SECTION); +#endif + BUILD_DIR/libultra.a:setcompare.o(.SECTION); + BUILD_DIR/libultra.a:thread.o(.SECTION); + BUILD_DIR/libultra.a:probetlb.o(.SECTION); + BUILD_DIR/libultra.a:resetglobalintmask.o(.SECTION); + BUILD_DIR/libultra.a:epirawwrite.o(.SECTION); +#if LIBULTRA_VERSION >= OS_VER_H + BUILD_DIR/libultra.a:epirawread.o(.SECTION); + BUILD_DIR/libultra.a:setglobalintmask.o(.SECTION); +#endif + BUILD_DIR/libultra.a:yieldthread.o(.SECTION); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:pfsgetstatus.o(.SECTION); +#endif + BUILD_DIR/libultra.a:lookatref.o(.SECTION); /* Fast3DEX2 only */ + BUILD_DIR/libultra.a:pfsselectbank.o(.SECTION); +#ifdef LIBULTRA_EXCLUSIVE + BUILD_DIR/libultra.a:driverominit.o(.SECTION); +#endif \ No newline at end of file diff --git a/lib/ultra/K_L.inc b/lib/ultra/K_L.inc new file mode 100644 index 00000000..3d5e5ba7 --- /dev/null +++ b/lib/ultra/K_L.inc @@ -0,0 +1,146 @@ + BUILD_DIR/libultra.a:wrapper.o(.SECTION); // BBPLAYER + BUILD_DIR/libultra.a:aigetlen.o(.SECTION); + BUILD_DIR/libultra.a:aisetfreq.o(.SECTION); + BUILD_DIR/libultra.a:aisetnextbuf.o(.SECTION); + BUILD_DIR/libultra.a:bnkf.o(.SECTION); + BUILD_DIR/libultra.a:invaldcache.o(.SECTION); + BUILD_DIR/libultra.a:invalicache.o(.SECTION); + BUILD_DIR/libultra.a:writebackdcacheall.o(.SECTION); + BUILD_DIR/libultra.a:contreaddata.o(.SECTION); + BUILD_DIR/libultra.a:controller.o(.SECTION); + BUILD_DIR/libultra.a:virtualtophysical.o(.SECTION); + BUILD_DIR/libultra.a:sqrtf.o(.SECTION); + BUILD_DIR/libultra.a:cosf.o(.SECTION); + BUILD_DIR/libultra.a:ortho.o(.SECTION); + BUILD_DIR/libultra.a:perspective.o(.SECTION); + BUILD_DIR/libultra.a:sinf.o(.SECTION); + BUILD_DIR/libultra.a:bcopy.o(.SECTION); + BUILD_DIR/libultra.a:bzero.o(.SECTION); + BUILD_DIR/libultra.a:ll.o(.SECTION); + BUILD_DIR/libultra.a:llcvt.o(.SECTION); + BUILD_DIR/libultra.a:string.o(.SECTION); + BUILD_DIR/libultra.a:xprintf.o(.SECTION); + BUILD_DIR/libultra.a:sprintf.o(.SECTION); + BUILD_DIR/libultra.a:syncprintf.o(.SECTION); + BUILD_DIR/libultra.a:createmesgqueue.o(.SECTION); + BUILD_DIR/libultra.a:recvmesg.o(.SECTION); + BUILD_DIR/libultra.a:sendmesg.o(.SECTION); + BUILD_DIR/libultra.a:seteventmesg.o(.SECTION); +#ifdef BBPLAYER + BUILD_DIR/libultra.a:_getcount.o(.SECTION); +#else + BUILD_DIR/libultra.a:getcount.o(.SECTION); +#endif + BUILD_DIR/libultra.a:sptask.o(.SECTION); + BUILD_DIR/libultra.a:sptaskyield.o(.SECTION); + BUILD_DIR/libultra.a:sptaskyielded.o(.SECTION); + BUILD_DIR/libultra.a:sirawdma.o(.SECTION); + BUILD_DIR/libultra.a:siacs.o(.SECTION); + BUILD_DIR/libultra.a:createthread.o(.SECTION); + BUILD_DIR/libultra.a:setthreadpri.o(.SECTION); + BUILD_DIR/libultra.a:startthread.o(.SECTION); + BUILD_DIR/libultra.a:thread.o(.SECTION); + BUILD_DIR/libultra.a:getcurrfaultthread.o(.SECTION); + BUILD_DIR/libultra.a:gettime.o(.SECTION); + BUILD_DIR/libultra.a:settime.o(.SECTION); + BUILD_DIR/libultra.a:settimer.o(.SECTION); + BUILD_DIR/libultra.a:timerintr.o(.SECTION); + BUILD_DIR/libultra.a:maptlb.o(.SECTION); + BUILD_DIR/libultra.a:probetlb.o(.SECTION); + BUILD_DIR/libultra.a:unmaptlball.o(.SECTION); + BUILD_DIR/libultra.a:vimgr.o(.SECTION); + BUILD_DIR/libultra.a:vitbl.o(.SECTION); + BUILD_DIR/libultra.a:visetevent.o(.SECTION); + BUILD_DIR/libultra.a:visetmode.o(.SECTION); + BUILD_DIR/libultra.a:visetspecial.o(.SECTION); + BUILD_DIR/libultra.a:viswapbuf.o(.SECTION); + BUILD_DIR/libultra.a:viswapcontext.o(.SECTION); + BUILD_DIR/libultra.a:viblack.o(.SECTION); + BUILD_DIR/libultra.a:mtxidentf.o(.SECTION); + BUILD_DIR/libultra.a:mtxf2l.o(.SECTION); + BUILD_DIR/libultra.a:scale.o(.SECTION); + BUILD_DIR/libultra.a:translate.o(.SECTION); + BUILD_DIR/libultra.a:rotate.o(.SECTION); + BUILD_DIR/libultra.a:conteepprobe.o(.SECTION); + BUILD_DIR/libultra.a:conteeplongwrite.o(.SECTION); + BUILD_DIR/libultra.a:conteeplongread.o(.SECTION); + BUILD_DIR/libultra.a:exceptasm.o(.SECTION); + BUILD_DIR/libultra.a:interrupt.o(.SECTION); + BUILD_DIR/libultra.a:setintmask.o(.SECTION); + BUILD_DIR/libultra.a:pimgr.o(.SECTION); + BUILD_DIR/libultra.a:epirawdma.o(.SECTION); + BUILD_DIR/libultra.a:epidma.o(.SECTION); + BUILD_DIR/libultra.a:cartrominit.o(.SECTION); + BUILD_DIR/libultra.a:devmgr.o(.SECTION); + BUILD_DIR/libultra.a:piacs.o(.SECTION); + BUILD_DIR/libultra.a:pidma.o(.SECTION); + BUILD_DIR/libultra.a:skapi.o(.SECTION); // BBPLAYER + BUILD_DIR/libultra.a:motor.o(.SECTION); + BUILD_DIR/libultra.a:parameters.o(.SECTION); + BUILD_DIR/libultra.a:initialize.o(.SECTION); + BUILD_DIR/libultra.a:ai.o(.SECTION); + BUILD_DIR/libultra.a:writebackdcache.o(.SECTION); + BUILD_DIR/libultra.a:libm_vals.o(.SECTION); + BUILD_DIR/libultra.a:xlitob.o(.SECTION); + BUILD_DIR/libultra.a:xldtob.o(.SECTION); + BUILD_DIR/libultra.a:jammesg.o(.SECTION); + BUILD_DIR/libultra.a:getcause.o(.SECTION); + BUILD_DIR/libultra.a:getsr.o(.SECTION); + BUILD_DIR/libultra.a:setfpccsr.o(.SECTION); + BUILD_DIR/libultra.a:setsr.o(.SECTION); + BUILD_DIR/libultra.a:setwatchlo.o(.SECTION); +#ifdef BBPLAYER + BUILD_DIR/libultra.a:_setcompare.o(.SECTION); +#else + BUILD_DIR/libultra.a:setcompare.o(.SECTION); +#endif + BUILD_DIR/libultra.a:sp.o(.SECTION); + BUILD_DIR/libultra.a:spgetstat.o(.SECTION); + BUILD_DIR/libultra.a:spsetstat.o(.SECTION); + BUILD_DIR/libultra.a:spsetpc.o(.SECTION); + BUILD_DIR/libultra.a:sprawdma.o(.SECTION); + BUILD_DIR/libultra.a:sirawread.o(.SECTION); + BUILD_DIR/libultra.a:sirawwrite.o(.SECTION); + BUILD_DIR/libultra.a:destroythread.o(.SECTION); + BUILD_DIR/libultra.a:getthreadpri.o(.SECTION); + BUILD_DIR/libultra.a:yieldthread.o(.SECTION); + BUILD_DIR/libultra.a:maptlbrdb.o(.SECTION); + BUILD_DIR/libultra.a:vi.o(.SECTION); + BUILD_DIR/libultra.a:vigetcurrcontext.o(.SECTION); + BUILD_DIR/libultra.a:normalize.o(.SECTION); + BUILD_DIR/libultra.a:conteepread.o(.SECTION); + BUILD_DIR/libultra.a:conteepwrite.o(.SECTION); + BUILD_DIR/libultra.a:setglobalintmask.o(.SECTION); + BUILD_DIR/libultra.a:resetglobalintmask.o(.SECTION); + BUILD_DIR/libultra.a:pirawdma.o(.SECTION); + BUILD_DIR/libultra.a:pigetcmdq.o(.SECTION); + BUILD_DIR/libultra.a:epirawread.o(.SECTION); + BUILD_DIR/libultra.a:epirawwrite.o(.SECTION); + BUILD_DIR/libultra.a:ldiv.o(.SECTION); + BUILD_DIR/libultra.a:si.o(.SECTION); + BUILD_DIR/libultra.a:pirawread.o(.SECTION); + BUILD_DIR/libultra.a:sethwinterrupt.o(.SECTION); + BUILD_DIR/libultra.a:piacs.o(.SECTION); + BUILD_DIR/libultra.a:epirawdma.o(.SECTION); + BUILD_DIR/libultra.a:devmgr.o(.SECTION); + BUILD_DIR/libultra.a:siacs.o(.SECTION); + BUILD_DIR/libultra.a:sirawdma.o(.SECTION); + BUILD_DIR/libultra.a:settimer.o(.SECTION); + BUILD_DIR/libultra.a:kdebugserver.o(.SECTION); + BUILD_DIR/libultra.a:vimodentsclan1.o(.SECTION); + BUILD_DIR/libultra.a:vimodepallan1.o(.SECTION); + BUILD_DIR/libultra.a:vimodempallan1.o(.SECTION); + BUILD_DIR/libultra.a:setintmask.o(.SECTION); + BUILD_DIR/libultra.a:lookatref.o(.SECTION); /* Fast3DEX2 only */ + BUILD_DIR/libultra.a:pfsselectbank.o(.SECTION); +#ifndef BBPLAYER + BUILD_DIR/libultra.a:leodiskinit.o(.SECTION); +#endif + BUILD_DIR/libultra.a:pfsgetstatus.o(.SECTION); + BUILD_DIR/libultra.a:pfsisplug.o(.SECTION); + BUILD_DIR/libultra.a:crc.o(.SECTION); + BUILD_DIR/libultra.a:contramwrite.o(.SECTION); + BUILD_DIR/libultra.a:contramread.o(.SECTION); +#ifdef LIBULTRA_EXCLUSIVE + BUILD_DIR/libultra.a:driverominit.o(.SECTION); +#endif \ No newline at end of file diff --git a/lib/ultra/audio/bnkf.c b/lib/ultra/audio/bnkf.c new file mode 100644 index 00000000..592a385c --- /dev/null +++ b/lib/ultra/audio/bnkf.c @@ -0,0 +1,114 @@ +#include "PR/os_internal.h" +#include "PR/libaudio.h" + +static void _bnkfPatchBank(ALBank *bank, ALBankFile *file, s32 table); +static void _bnkfPatchInst(ALInstrument *inst, ALBankFile *file, s32 table); +static void _bnkfPatchSound(ALSound *sound, ALBankFile *file, s32 table); +static void _bnkfPatchWaveTable(ALWaveTable *wvtbl, ALBankFile *file, s32 table); + +void alSeqFileNew(ALSeqFile *file, u8 *base) +{ + uintptr_t b = (uintptr_t) base; + int i; + + /* + * patch the file so that offsets are pointers + */ + for (i = 0; i < file->seqCount; i++) { + file->seqArray[i].offset = ALBnkfPatch(file->seqArray[i].offset, b, u8 *); + } +} + +void alBnkfNew(ALBankFile *file, u8 *table) +{ + uintptr_t t = (uintptr_t) table; + int i; + + /* + * check the file format revision in debug libraries + */ + ALFailIf(file->revision != AL_BANK_VERSION, ERR_ALBNKFNEW); + + /* + * patch the file so that offsets are pointers + */ + for (i = 0; i < file->bankCount; i++) { + file->bankArray[i] = ALBnkfPatch(file->bankArray[i], file, ALBank *); + if(file->bankArray[i]) + _bnkfPatchBank(file->bankArray[i], file, t); + } +} + +void _bnkfPatchBank(ALBank *bank, ALBankFile *file, s32 table) +{ + int i; + + if (bank->flags) + return; + + bank->flags = 1; + + if (bank->percussion) { + bank->percussion = ALBnkfPatch(bank->percussion, file, ALInstrument *); + _bnkfPatchInst(bank->percussion, file, table); + } + + for (i = 0; i < bank->instCount; i++) { + bank->instArray[i] = ALBnkfPatch(bank->instArray[i], file, ALInstrument *); + if(bank->instArray[i]) + _bnkfPatchInst(bank->instArray[i], file, table); + } +} + +void _bnkfPatchInst(ALInstrument *inst, ALBankFile *file, s32 table) +{ + int i; + + if (inst->flags) + return; + + inst->flags = 1; + + for (i = 0; i < inst->soundCount; i++) { + inst->soundArray[i] = ALBnkfPatch(inst->soundArray[i], file, ALSound *); + _bnkfPatchSound(inst->soundArray[i], file, table); + + } +} + +void _bnkfPatchSound(ALSound *sound, ALBankFile *file, s32 table) +{ + if (sound->flags) + return; + + sound->flags = 1; + + sound->envelope = ALBnkfPatch(sound->envelope, file, ALEnvelope *); + sound->keyMap = ALBnkfPatch(sound->keyMap, file, ALKeyMap *); + + sound->wavetable = ALBnkfPatch(sound->wavetable, file, ALWaveTable *); + _bnkfPatchWaveTable(sound->wavetable, file, table); +} + +void _bnkfPatchWaveTable(ALWaveTable *wvtbl, ALBankFile *file, s32 table) +{ + if (wvtbl->flags) + return; + + wvtbl->flags = 1; + + wvtbl->base += table; + + /* sct 2/14/96 - patch wavetable loop info based on type. */ + if (wvtbl->type == AL_ADPCM_WAVE) + { + wvtbl->waveInfo.adpcmWave.book = ALBnkfPatch(wvtbl->waveInfo.adpcmWave.book, file, ALADPCMBook *); + if (wvtbl->waveInfo.adpcmWave.loop) + wvtbl->waveInfo.adpcmWave.loop = ALBnkfPatch(wvtbl->waveInfo.adpcmWave.loop, file, ALADPCMloop *); + } + else if (wvtbl->type == AL_RAW16_WAVE) + { + if (wvtbl->waveInfo.rawWave.loop) + wvtbl->waveInfo.rawWave.loop = ALBnkfPatch(wvtbl->waveInfo.rawWave.loop, file, ALRawLoop *); + } +} diff --git a/lib/ultra/bb/os/_getcount.c b/lib/ultra/bb/os/_getcount.c new file mode 100644 index 00000000..e16b0e1c --- /dev/null +++ b/lib/ultra/bb/os/_getcount.c @@ -0,0 +1,35 @@ +#include "PR/os_internal.h" + +#ifdef BBPLAYER + +u32 __osBbLastRCount; +u32 __osBbRCountWraps; +u32 __osBbLastVCount; +u32 __osBbVCountWraps; + +u32 osGetCount(void) { + u32 count; + u32 mask; + + mask = __osDisableInt(); + + __asm__("mfc0 %0, $9" : "=r"(count)); // $9 = C0_COUNT + + if (count < __osBbLastRCount) { + __osBbRCountWraps++; + } + __osBbLastRCount = count; + + count = (((u64)__osBbRCountWraps << 32) | count) * 125ull / 192ull; + + if (count < __osBbLastVCount) { + __osBbVCountWraps++; + } + __osBbLastVCount = count; + + __osRestoreInt(mask); + + return count; +} + +#endif diff --git a/lib/ultra/bb/os/_setcompare.c b/lib/ultra/bb/os/_setcompare.c new file mode 100644 index 00000000..0997e7cb --- /dev/null +++ b/lib/ultra/bb/os/_setcompare.c @@ -0,0 +1,22 @@ +#include "PR/os_internal.h" + +#ifdef BBPLAYER + +extern u32 __osBbLastRCount; +extern u32 __osBbRCountWraps; +extern u32 __osBbLastVCount; +extern u32 __osBbVCountWraps; + +void __osSetCompare(u32 v) { + if (v != 0) { + u32 mask = __osDisableInt(); + u32 wraps = (v < __osBbLastVCount) ? __osBbVCountWraps + 1 : __osBbVCountWraps; + + v = (((u64)wraps << 32) | v) * 192ull / 125ull; + + __osRestoreInt(mask); + } + __asm__ ("mtc0 %0, $11" :: "r"(v)); // $11 = C0_COMPARE +} + +#endif diff --git a/lib/ultra/bb/sk/skapi.s b/lib/ultra/bb/sk/skapi.s new file mode 100644 index 00000000..a4bb5181 --- /dev/null +++ b/lib/ultra/bb/sk/skapi.s @@ -0,0 +1,44 @@ +#include "sys/asm.h" +#include "sys/regdef.h" +#include "PR/R4300.h" +#include "PR/ultratypes.h" +#include "PR/bcp.h" +#include "PR/rcp.h" + +#ifdef BBPLAYER + +#define SK_FUNC(name, num) \ + LEAF(name) ;\ + .set noreorder ;\ + li v0, num ;\ + li t0, PHYS_TO_K1(0x04300014) ;\ + lw t1, (t0) ;\ + nop ;\ + jr ra ;\ + nop ;\ + .set reorder ;\ + END(name) + +SK_FUNC(skGetId, 0) +SK_FUNC(skLaunchSetup, 1) +SK_FUNC(skLaunch, 2) +SK_FUNC(skRecryptListValid, 3) +SK_FUNC(skRecryptBegin, 4) +SK_FUNC(skRecryptData, 5) +SK_FUNC(skRecryptComputeState, 6) +SK_FUNC(skRecryptEnd, 7) +SK_FUNC(skSignHash, 8) +SK_FUNC(skVerifyHash, 9) +SK_FUNC(skGetConsumption, 10) +SK_FUNC(skAdvanceTicketWindow, 11) +SK_FUNC(skSetLimit, 12) +SK_FUNC(skExit, 13) +SK_FUNC(skKeepAlive, 14) +SK_FUNC(skGetRandomKeyData, 15) +SK_FUNC(skDumpVirage, 16) +SK_FUNC(skTest2, 17) +SK_FUNC(skTest3, 18) +SK_FUNC(skResetWindow, 19) +SK_FUNC(skValidateRls, 20) + +#endif diff --git a/lib/src/osInitializeIQueWrapper.c b/lib/ultra/bb/wrapper.c similarity index 90% rename from lib/src/osInitializeIQueWrapper.c rename to lib/ultra/bb/wrapper.c index a65157da..74103e2c 100644 --- a/lib/src/osInitializeIQueWrapper.c +++ b/lib/ultra/bb/wrapper.c @@ -1,7 +1,6 @@ #include "ultra64.h" -#include "PR/os.h" -#ifdef VERSION_CN +#ifdef BBPLAYER s32 osMotorStart(OSPfs *pfs) { return __osMotorAccess(pfs, MOTOR_START); } diff --git a/lib/src/kdebugserver.c b/lib/ultra/debug/kdebugserver.c similarity index 64% rename from lib/src/kdebugserver.c rename to lib/ultra/debug/kdebugserver.c index 2515763b..fce5a8b2 100644 --- a/lib/src/kdebugserver.c +++ b/lib/ultra/debug/kdebugserver.c @@ -1,90 +1,103 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" +#include "PR/rcp.h" #include "PR/rdb.h" -#ifndef VERSION_CN +#if LIBULTRA_VERSION <= OS_VER_D || !defined(_FINALROM) static s32 debugState = 0; static s32 numChars = 0; static s32 numCharsToReceive = 0; -#endif -extern u8 debugBuffer[0x100]; +static u8 debugBuffer[0x100]; +#endif OSThread __osThreadSave; -#ifndef VERSION_CN -void u32_to_string(u32 i, u8 *str) { - str[0] = (i >> 0x18) & 0xff; - str[1] = (i >> 0x10) & 0xff; - str[2] = (i >> 0x8) & 0xff; - str[3] = i & 0xff; +#if LIBULTRA_VERSION <= OS_VER_D || !defined(_FINALROM) +static void u32_to_string(u32 k, u8 *s) { + s[0] = (k >> 0x18) & 0xff; + s[1] = (k >> 0x10) & 0xff; + s[2] = (k >> 0x8) & 0xff; + s[3] = k & 0xff; } -u32 string_to_u32(u8 *str) { - u32 i; - i = (str[0] & 0xff) << 0x18; - i |= (str[1] & 0xff) << 0x10; - i |= (str[2] & 0xff) << 0x8; - i |= (str[3] & 0xff); - return i; +static u32 string_to_u32(u8 *s) { + u32 k; + + k = (s[0] & 0xff) << 0x18; + k |= (s[1] & 0xff) << 0x10; + k |= (s[2] & 0xff) << 0x8; + k |= (s[3] & 0xff); + + return k; } -void send_packet(u8 *a0, s32 a1) { +static void send_packet(u8 *s, s32 n) { rdbPacket pkt; s32 i; + pkt.type = 2; - for (pkt.length = a1, i = 0; i < a1; i++) { - pkt.buf[i] = a0[i]; + + for (pkt.length = n, i = 0; i < n; i++) { + pkt.buf[i] = s[i]; } *(volatile u32 *) RDB_BASE_REG = *(u32 *) &pkt; - while (!(__osGetCause() & 0x2000)) { + + while (!(__osGetCause() & CAUSE_IP6)) { ; } *(volatile u32 *) RDB_READ_INTR_REG = 0; } -void send(u8 *buff, s32 len) { +static void send(u8 *buff, s32 len) { s32 i; s32 end; s32 rem; + if (!__osRdbWriteOK) { - while (!(__osGetCause() & 0x2000)) { + while (!(__osGetCause() & CAUSE_IP6)) { ; } *(volatile u32 *) RDB_READ_INTR_REG = 0; __osRdbWriteOK = 1; } + i = 0; rem = len % 3; end = len - rem; + for (; i < end; i += 3) { send_packet(&buff[i], 3); } + if (rem > 0) { send_packet(&buff[end], rem); } } -void process_command_memory(void) { - u32 sp1c; - u32 sp18; - sp1c = string_to_u32(&debugBuffer[1]); - sp18 = string_to_u32(&debugBuffer[5]); - send((u8 *) (uintptr_t) sp1c, sp18); +static void process_command_memory(void) { + u32 buff = string_to_u32(&debugBuffer[1]); + u32 size = string_to_u32(&debugBuffer[5]); + + send((u8 *) (uintptr_t) buff, size); } -void process_command_register(void) { +static void process_command_register(void) { send((u8 *) &__osThreadSave.context, sizeof(__OSThreadContext)); } -void kdebugserver(u32 a0) { - u32 sp2c; +void kdebugserver(u32 packet) { + u32 i; rdbPacket pkt; - *(u32 *) &pkt = a0; - for (sp2c = 0; sp2c < pkt.length; sp2c++) { - debugBuffer[numChars] = pkt.buf[sp2c]; + + *(u32 *) &pkt = packet; + + for (i = 0; i < pkt.length; i++) { + debugBuffer[numChars] = pkt.buf[i]; numChars++; } + numCharsToReceive -= pkt.length; + switch (debugState) { case 0: switch (pkt.buf[0]) { diff --git a/lib/ultra/gu/cosf.c b/lib/ultra/gu/cosf.c new file mode 100644 index 00000000..2f21d535 --- /dev/null +++ b/lib/ultra/gu/cosf.c @@ -0,0 +1,125 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +/* ==================================================================== + * ==================================================================== + * + * Module: fcos.c + * $Revision: 1.3 $ + * $Date: 1998/10/09 06:10:53 $ + * $Author: has $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/libultra/monegi/gu/cosf.c,v $ + * + * Revision history: + * 09-Jun-93 - Original Version + * + * Description: source code for fcos function + * + * ==================================================================== + * ==================================================================== + */ + +/* coefficients for polynomial approximation of cos on +/- pi/2 */ + +static const du P[] = { +{{0x3ff00000, 0x00000000}}, +{{0xbfc55554, 0xbc83656d}}, +{{0x3f8110ed, 0x3804c2a0}}, +{{0xbf29f6ff, 0xeea56814}}, +{{0x3ec5dbdf, 0x0e314bfe}}, +}; + +static const du rpi = { +{0x3fd45f30, 0x6dc9c883} +}; + +static const du pihi = { +{0x400921fb, 0x50000000} +}; + +static const du pilo = { +{0x3e6110b4, 0x611a6263} +}; + +static const fu zero = {0x00000000}; + +float cosf(float x) +{ +float absx; +double dx, xsq, poly; +double dn; +int n; +double result; +int ix, xpt; + + + ix = *(int *)&x; + xpt = (ix >> 22); + xpt &= 0x1ff; + + /* xpt is exponent(x) + 1 bit of mantissa */ + + + if ( xpt < 0x136 ) + { + /* |x| < 2^28 */ + + /* use the standard algorithm from Cody and Waite, doing + the computations in double precision + */ + + absx = ABS(x); + + dx = absx; + + dn = dx*rpi.d + 0.5; + n = ROUND(dn); + dn = n; + + dn -= 0.5; + + dx = dx - dn*pihi.d; + dx = dx - dn*pilo.d; /* dx = x - (n - 0.5)*pi */ + + xsq = dx*dx; + + poly = ((P[4].d*xsq + P[3].d)*xsq + P[2].d)*xsq + P[1].d; + + result = dx + (dx*xsq)*poly; + + /* negate result if n is odd */ + + if ( (n & 1) == 0 ) + return ( (float)result ); + + return ( -(float)result ); + } + + if ( x != x ) + { + /* x is a NaN; return a quiet NaN */ + +#ifdef _IP_NAN_SETS_ERRNO + + *__errnoaddr = EDOM; +#endif + + return ( __libm_qnan.f ); + } + + /* just give up and return 0.0 */ + + return ( zero.f ); +} diff --git a/lib/ultra/gu/guint.h b/lib/ultra/gu/guint.h new file mode 100644 index 00000000..ff819f17 --- /dev/null +++ b/lib/ultra/gu/guint.h @@ -0,0 +1,45 @@ +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "PR/mbi.h" +#include "PR/gu.h" +#include "PR/os_version.h" + +typedef union +{ + struct + { + unsigned int hi; + unsigned int lo; + } word; + + double d; +} du; + +typedef union +{ + unsigned int i; + float f; +} fu; + +#ifndef __GL_GL_H__ + +typedef float Matrix[4][4]; + +#endif + +#define ROUND(d) (int)(((d) >= 0.0) ? ((d) + 0.5) : ((d) - 0.5)) +#ifndef ABS +#define ABS(d) ((d) > 0) ? (d) : -(d) +#endif + +extern const fu __libm_qnan; diff --git a/lib/ultra/gu/libm_vals.c b/lib/ultra/gu/libm_vals.c new file mode 100644 index 00000000..d3d845e7 --- /dev/null +++ b/lib/ultra/gu/libm_vals.c @@ -0,0 +1,15 @@ +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +const fu __libm_qnan = { 0x7f810000 }; diff --git a/lib/src/guLookAtRef.c b/lib/ultra/gu/lookatref.c similarity index 68% rename from lib/src/guLookAtRef.c rename to lib/ultra/gu/lookatref.c index 4e65a49a..9dd964bf 100644 --- a/lib/src/guLookAtRef.c +++ b/lib/ultra/gu/lookatref.c @@ -1,30 +1,32 @@ /* * This file originates from the standard Nintendo 64 SDK libultra src * directory, and it used exclusively when building with the Fast3DEX2 - * microcode. Not not using it breaks environment mapping. + * microcode. Not using it breaks environment mapping. * * Apart from the modifications listed below, this file is unmodified. */ /************************************************************************** - * * - * Copyright (C) 1994, Silicon Graphics, Inc. * - * * + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * * These coded instructions, statements, and computer programs contain * * unpublished proprietary information of Silicon Graphics, Inc., and * * are protected by Federal copyright law. They may not be disclosed * * to third parties or copied or duplicated in any form, in whole or * * in part, without the prior written consent of Silicon Graphics, Inc. * - * * + * * **************************************************************************/ -/* Minor modifications */ -#include -#define FTOFRAC8(x) ((int) MIN(((x) * (128.0)), 127.0) & 0xff) +#include "guint.h" -void guLookAtReflectF(float mf[4][4], LookAt *l, float xEye, float yEye, float zEye, float xAt, - float yAt, float zAt, float xUp, float yUp, float zUp) { - float len, xLook, yLook, zLook, xRight, yRight, zRight; + +void guLookAtReflectF(float mf[4][4], LookAt *l, + float xEye, float yEye, float zEye, + float xAt, float yAt, float zAt, + float xUp, float yUp, float zUp) +{ + float len, xLook, yLook, zLook, xRight, yRight, zRight; guMtxIdentF(mf); @@ -33,7 +35,7 @@ void guLookAtReflectF(float mf[4][4], LookAt *l, float xEye, float yEye, float z zLook = zAt - zEye; /* Negate because positive Z is behind us: */ - len = -1.0 / sqrtf(xLook * xLook + yLook * yLook + zLook * zLook); + len = -1.0 / sqrtf (xLook*xLook + yLook*yLook + zLook*zLook); xLook *= len; yLook *= len; zLook *= len; @@ -43,7 +45,7 @@ void guLookAtReflectF(float mf[4][4], LookAt *l, float xEye, float yEye, float z xRight = yUp * zLook - zUp * yLook; yRight = zUp * xLook - xUp * zLook; zRight = xUp * yLook - yUp * xLook; - len = 1.0 / sqrtf(xRight * xRight + yRight * yRight + zRight * zRight); + len = 1.0 / sqrtf (xRight*xRight + yRight*yRight + zRight*zRight); xRight *= len; yRight *= len; zRight *= len; @@ -53,7 +55,7 @@ void guLookAtReflectF(float mf[4][4], LookAt *l, float xEye, float yEye, float z xUp = yLook * zRight - zLook * yRight; yUp = zLook * xRight - xLook * zRight; zUp = xLook * yRight - yLook * xRight; - len = 1.0 / sqrtf(xUp * xUp + yUp * yUp + zUp * zUp); + len = 1.0 / sqrtf (xUp*xUp + yUp*yUp + zUp*zUp); xUp *= len; yUp *= len; zUp *= len; @@ -104,11 +106,14 @@ void guLookAtReflectF(float mf[4][4], LookAt *l, float xEye, float yEye, float z mf[3][3] = 1; } -void guLookAtReflect(Mtx *m, LookAt *l, float xEye, float yEye, float zEye, float xAt, float yAt, - float zAt, float xUp, float yUp, float zUp) { - float mf[4][4]; +void guLookAtReflect (Mtx *m, LookAt *l, float xEye, float yEye, float zEye, + float xAt, float yAt, float zAt, + float xUp, float yUp, float zUp) +{ + float mf[4][4]; - guLookAtReflectF(mf, l, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp); + guLookAtReflectF(mf, l, xEye, yEye, zEye, xAt, yAt, zAt, + xUp, yUp, zUp); guMtxF2L(mf, m); } diff --git a/lib/ultra/gu/mtxutil.c b/lib/ultra/gu/mtxutil.c new file mode 100644 index 00000000..70c0d1e9 --- /dev/null +++ b/lib/ultra/gu/mtxutil.c @@ -0,0 +1,90 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" +#ifdef GBI_FLOATS +#include +#endif + +#if LIBULTRA_VERSION < OS_VER_K || !defined(TARGET_N64) +#ifndef GBI_FLOATS +void guMtxF2L(float mf[4][4], Mtx *m) +{ + int i, j; + int e1,e2; + int *ai,*af; + + + ai=(int *) &m->m[0][0]; + af=(int *) &m->m[2][0]; + + for (i=0; i<4; i++) + for (j=0; j<2; j++) { + e1=FTOFIX32(mf[i][j*2]); + e2=FTOFIX32(mf[i][j*2+1]); + *(ai++) = ( e1 & 0xffff0000 ) | ((e2 >> 16)&0xffff); + *(af++) = ((e1 << 16) & 0xffff0000) | (e2 & 0xffff); + } +} + +void guMtxL2F(float mf[4][4], Mtx *m) +{ + int i, j; + unsigned int e1,e2; + unsigned int *ai,*af; + int q1,q2; + + ai=(unsigned int *) &m->m[0][0]; + af=(unsigned int *) &m->m[2][0]; + + for (i=0; i<4; i++) + for (j=0; j<2; j++) { + e1 = (*ai & 0xffff0000) | ((*af >> 16) & 0xffff); + e2 = ((*(ai++) << 16) & 0xffff0000) | (*(af++) & 0xffff); + q1 = *((int *)&e1); + q2 = *((int *)&e2); + + mf[i][j*2] = FIX32TOF(q1); + mf[i][j*2+1] = FIX32TOF(q2); + } +} +#else +void guMtxF2L(float mf[4][4], Mtx *m) { + memcpy(m, mf, sizeof(Mtx)); +} +#endif + +void guMtxIdentF(float mf[4][4]) +{ + int i, j; + + for (i=0; i<4; i++) + for (j=0; j<4; j++) + if (i == j) mf[i][j] = 1.0; + else mf[i][j] = 0.0; +} + +void guMtxIdent(Mtx *m) +{ +#ifndef GBI_FLOATS + float mf[4][4]; + + guMtxIdentF(mf); + + guMtxF2L(mf, m); +#else + guMtxIdentF(m->m); +#endif +} + +#endif diff --git a/lib/ultra/gu/normalize.c b/lib/ultra/gu/normalize.c new file mode 100644 index 00000000..27172b0a --- /dev/null +++ b/lib/ultra/gu/normalize.c @@ -0,0 +1,28 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +#if LIBULTRA_VERSION < OS_VER_K || !defined(TARGET_N64) + +void guNormalize(float *x, float *y, float *z) +{ + float m; + + m = 1/sqrtf((*x)*(*x) + (*y)*(*y) + (*z)*(*z)); + *x *= m; + *y *= m; + *z *= m; +} + +#endif diff --git a/lib/ultra/gu/ortho.c b/lib/ultra/gu/ortho.c new file mode 100644 index 00000000..15efbf42 --- /dev/null +++ b/lib/ultra/gu/ortho.c @@ -0,0 +1,42 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +void guOrthoF(float mf[4][4], float l, float r, float b, float t, float n, float f, float scale) +{ + int i, j; + + guMtxIdentF(mf); + + mf[0][0] = 2/(r-l); + mf[1][1] = 2/(t-b); + mf[2][2] = -2/(f-n); + mf[3][0] = -(r+l)/(r-l); + mf[3][1] = -(t+b)/(t-b); + mf[3][2] = -(f+n)/(f-n); + mf[3][3] = 1; + + for (i=0; i<4; i++) + for (j=0; j<4; j++) + mf[i][j] *= scale; +} + +void guOrtho(Mtx *m, float l, float r, float b, float t, float n, float f, float scale) +{ + Matrix mf; + + guOrthoF(mf, l, r, b, t, n, f, scale); + + guMtxF2L(mf, m); +} diff --git a/lib/ultra/gu/perspective.c b/lib/ultra/gu/perspective.c new file mode 100644 index 00000000..f5f9fc84 --- /dev/null +++ b/lib/ultra/gu/perspective.c @@ -0,0 +1,55 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +void guPerspectiveF(float mf[4][4], u16 *perspNorm, float fovy, float aspect, float near, float far, float scale) +{ + float cot; + int i, j; + + guMtxIdentF(mf); + + fovy *= GU_PI / 180.0; + cot = cosf (fovy/2) / sinf (fovy/2); + + mf[0][0] = cot / aspect; + mf[1][1] = cot; + mf[2][2] = (near + far) / (near - far); + mf[2][3] = -1; + mf[3][2] = (2 * near * far) / (near - far); + mf[3][3] = 0; + + for (i=0; i<4; i++) + for (j=0; j<4; j++) + mf[i][j] *= scale; + + if (perspNorm != (u16 *) NULL) { + if (near+far<=2.0) { + *perspNorm = (u16) 0xFFFF; + } else { + *perspNorm = (u16) ((2.0*65536.0)/(near+far)); + if (*perspNorm<=0) + *perspNorm = (u16) 0x0001; + } + } +} + +void guPerspective(Mtx *m, u16 *perspNorm, float fovy, float aspect, float near, float far, float scale) +{ + Matrix mf; + + guPerspectiveF(mf, perspNorm, fovy, aspect, near, far, scale); + + guMtxF2L(mf, m); +} diff --git a/lib/ultra/gu/rotate.c b/lib/ultra/gu/rotate.c new file mode 100644 index 00000000..901a1793 --- /dev/null +++ b/lib/ultra/gu/rotate.c @@ -0,0 +1,71 @@ +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +void guRotateF(float mf[4][4], float a, float x, float y, float z) +{ + static float dtor = GU_PI / 180.0; + float sine; + float cosine; + float ab, bc, ca, t; +#if LIBULTRA_VERSION >= OS_VER_K + float xxsine; + float yxsine; + float zxsine; +#endif + + guNormalize(&x, &y, &z); + a *= dtor; + sine = sinf(a); + cosine = cosf(a); + t = (1-cosine); + ab = x*y*t; + bc = y*z*t; + ca = z*x*t; + + guMtxIdentF(mf); + +#if LIBULTRA_VERSION >= OS_VER_K + xxsine = x * sine; + yxsine = y * sine; + zxsine = z * sine; +#else + #define xxsine (x * sine) + #define yxsine (y * sine) + #define zxsine (z * sine) +#endif + + t = x*x; + mf[0][0] = t+cosine*(1-t); + mf[2][1] = bc-xxsine; + mf[1][2] = bc+xxsine; + + t = y*y; + mf[1][1] = t+cosine*(1-t); + mf[2][0] = ca+yxsine; + mf[0][2] = ca-yxsine; + + t = z*z; + mf[2][2] = t+cosine*(1-t); + mf[1][0] = ab-zxsine; + mf[0][1] = ab+zxsine; +} + +void guRotate(Mtx *m, float a, float x, float y, float z) +{ + Matrix mf; + + guRotateF(mf, a, x, y, z); + + guMtxF2L(mf, m); +} diff --git a/lib/ultra/gu/scale.c b/lib/ultra/gu/scale.c new file mode 100644 index 00000000..1a202e37 --- /dev/null +++ b/lib/ultra/gu/scale.c @@ -0,0 +1,37 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +#if LIBULTRA_VERSION < OS_VER_K || !defined(TARGET_N64) + +void guScaleF(float mf[4][4], float x, float y, float z) +{ + guMtxIdentF(mf); + + mf[0][0] = x; + mf[1][1] = y; + mf[2][2] = z; + mf[3][3] = 1; +} + +void guScale(Mtx *m, float x, float y, float z) +{ + Matrix mf; + + guScaleF(mf, x, y, z); + + guMtxF2L(mf, m); +} + +#endif diff --git a/lib/ultra/gu/sinf.c b/lib/ultra/gu/sinf.c new file mode 100644 index 00000000..5a8f35ae --- /dev/null +++ b/lib/ultra/gu/sinf.c @@ -0,0 +1,144 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +/* ==================================================================== + * ==================================================================== + * + * Module: fsin.c + * $Revision: 1.3 $ + * $Date: 1998/10/09 06:14:51 $ + * $Author: has $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/libultra/monegi/gu/sinf.c,v $ + * + * Revision history: + * 09-Jun-93 - Original Version + * + * Description: source code for fsin function + * + * ==================================================================== + * ==================================================================== + */ + +/* coefficients for polynomial approximation of sin on +/- pi/2 */ + +static const du P[] = { +{{0x3ff00000, 0x00000000}}, +{{0xbfc55554, 0xbc83656d}}, +{{0x3f8110ed, 0x3804c2a0}}, +{{0xbf29f6ff, 0xeea56814}}, +{{0x3ec5dbdf, 0x0e314bfe}}, +}; + +static const du rpi = { +{0x3fd45f30, 0x6dc9c883} +}; + +static const du pihi = { +{0x400921fb, 0x50000000} +}; + +static const du pilo = { +{0x3e6110b4, 0x611a6263} +}; + +static const fu zero = {0x00000000}; + +float sinf(float x) +{ +double dx, xsq, poly; +double dn; +int n; +double result; +int ix, xpt; + + + ix = *(int *)&x; + xpt = (ix >> 22); + xpt &= 0x1ff; + + /* xpt is exponent(x) + 1 bit of mantissa */ + + if ( xpt < 0xff ) + { + /* |x| < 1.5 */ + + dx = x; + + if ( xpt >= 0xe6 ) + { + /* |x| >= 2^(-12) */ + + /* compute sin(x) with a standard polynomial approximation */ + + xsq = dx*dx; + + poly = ((P[4].d*xsq + P[3].d)*xsq + P[2].d)*xsq + P[1].d; + + result = dx + (dx*xsq)*poly; + + return ( (float)result ); + } + + return ( x ); + } + + if ( xpt < 0x136 ) + { + /* |x| < 2^28 */ + + dx = x; + + /* reduce argument to +/- pi/2 */ + + dn = dx*rpi.d; + + n = ROUND(dn); + dn = n; + + dx = dx - dn*pihi.d; + dx = dx - dn*pilo.d; /* dx = x - n*pi */ + + /* compute sin(dx) as before, negating result if n is odd + */ + + xsq = dx*dx; + + poly = ((P[4].d*xsq + P[3].d)*xsq + P[2].d)*xsq + P[1].d; + + result = dx + (dx*xsq)*poly; + + + if ( (n & 1) == 0 ) + return ( (float)result ); + + return ( -(float)result ); + } + + if ( x != x ) + { + /* x is a NaN; return a quiet NaN */ + +#ifdef _IP_NAN_SETS_ERRNO + + *__errnoaddr = EDOM; +#endif + + return ( __libm_qnan.f ); + } + + /* just give up and return 0.0 */ + + return ( zero.f ); +} diff --git a/lib/ultra/gu/sqrtf.s b/lib/ultra/gu/sqrtf.s new file mode 100644 index 00000000..d62ece09 --- /dev/null +++ b/lib/ultra/gu/sqrtf.s @@ -0,0 +1,25 @@ +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/* + * Due to compiler bug, it won't insert a sqrt.s opcode in the stream so we + * make a function and call it for now. When compiler fixed, also remove the + * seperate Makefile rules + */ + +#include "sys/asm.h" +#include "sys/regdef.h" + +LEAF(sqrtf) + sqrt.s fv0, fa0 + j ra +END(sqrtf) diff --git a/lib/ultra/gu/translate.c b/lib/ultra/gu/translate.c new file mode 100644 index 00000000..e864d9d2 --- /dev/null +++ b/lib/ultra/gu/translate.c @@ -0,0 +1,36 @@ + +/************************************************************************** + * * + * Copyright (C) 1994, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#include "guint.h" + +#if LIBULTRA_VERSION < OS_VER_K || !defined(TARGET_N64) + +void guTranslateF(float mf[4][4], float x, float y, float z) +{ + guMtxIdentF(mf); + + mf[3][0] = x; + mf[3][1] = y; + mf[3][2] = z; +} + +void guTranslate(Mtx *m, float x, float y, float z) +{ + Matrix mf; + + guTranslateF(mf, x, y, z); + + guMtxF2L(mf, m); +} + +#endif diff --git a/lib/src/__osAiDeviceBusy.c b/lib/ultra/io/ai.c similarity index 64% rename from lib/src/__osAiDeviceBusy.c rename to lib/ultra/io/ai.c index b7ec5626..a85bf372 100644 --- a/lib/src/__osAiDeviceBusy.c +++ b/lib/ultra/io/ai.c @@ -1,11 +1,12 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/rcp.h" s32 __osAiDeviceBusy(void) { register s32 status = IO_READ(AI_STATUS_REG); + if (status & AI_STATUS_FIFO_FULL) { - return 1; - } else { - return 0; + return TRUE; } + + return FALSE; } diff --git a/lib/src/osAiGetLength.c b/lib/ultra/io/aigetlen.c similarity index 71% rename from lib/src/osAiGetLength.c rename to lib/ultra/io/aigetlen.c index ba730b62..582f180c 100644 --- a/lib/src/osAiGetLength.c +++ b/lib/ultra/io/aigetlen.c @@ -1,4 +1,3 @@ -#include "libultra_internal.h" #include "PR/rcp.h" u32 osAiGetLength() { diff --git a/lib/src/osAiSetFrequency.c b/lib/ultra/io/aisetfreq.c similarity index 54% rename from lib/src/osAiSetFrequency.c rename to lib/ultra/io/aisetfreq.c index 5aaee8a8..cc04e022 100644 --- a/lib/src/osAiSetFrequency.c +++ b/lib/ultra/io/aisetfreq.c @@ -1,42 +1,32 @@ -#include "libultra_internal.h" #include "PR/rcp.h" -#include "osint.h" -#include "macros.h" +#include "../os/osint.h" -s32 osAiSetFrequency(u32 freq) { +s32 osAiSetFrequency(u32 frequency) { register u32 dacRate; -#ifdef VERSION_CN +#if LIBULTRA_VERSION >= OS_VER_J register u32 bitRate; #else register s32 bitRate; #endif - register float ftmp; - ftmp = osViClock / (float) freq + .5f; + register float f; - dacRate = ftmp; + f = osViClock / (float) frequency + .5f; + dacRate = f; if (dacRate < AI_MIN_DAC_RATE) { return -1; } bitRate = (dacRate / 66) & 0xff; + if (bitRate > AI_MAX_BIT_RATE) { bitRate = AI_MAX_BIT_RATE; } IO_WRITE(AI_DACRATE_REG, dacRate - 1); IO_WRITE(AI_BITRATE_REG, bitRate - 1); -#ifndef VERSION_CN +#if LIBULTRA_VERSION < OS_VER_J IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON); #endif return osViClock / (s32) dacRate; } - -#if !defined(VERSION_SH) && !defined(VERSION_CN) -// put some extra jr $ra's down there please -UNUSED static void filler1(void) { -} - -UNUSED static void filler2(void) { -} -#endif diff --git a/lib/ultra/io/aisetnextbuf.c b/lib/ultra/io/aisetnextbuf.c new file mode 100644 index 00000000..24a15d30 --- /dev/null +++ b/lib/ultra/io/aisetnextbuf.c @@ -0,0 +1,55 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "../os/osint.h" + +/** + * It is worth noting that a previous hardware bug has been fixed by a software + * patch in osAiSetNextBuffer. This bug occurred when the address of the end of the + * buffer specified by osAiSetNextBuffer was at a specific value. This value + * occurred when the following was true: + * + * Prior 2.0I: (vaddr + nbytes) & 0x00003FFF == 0x2000 + * After 2.0I: (vaddr + nbytes) & 0x00001FFF == 0x0000 + * + * In this case, the DMA transfer does not complete successfully. This can cause + * clicks and pops in the audio output. This bug no longer requires special handling + * by the application because it is now patched by osAiSetNextBuffer. + */ + +s32 osAiSetNextBuffer(void *bufPtr, u32 size) { + static u8 hdwrBugFlag = FALSE; + char *bptr; + +#if LIBULTRA_VERSION >= OS_VER_J + if (__osAiDeviceBusy()) { + return -1; + } +#endif + + bptr = bufPtr; + + if (hdwrBugFlag) { + bptr -= 0x2000; + } + +#if LIBULTRA_VERSION >= OS_VER_I + if ((((uintptr_t) bufPtr + size) & 0x1fff) == 0) +#else + if ((((uintptr_t) bufPtr + size) & 0x3fff) == 0x2000) +#endif + { + hdwrBugFlag = TRUE; + } else { + hdwrBugFlag = FALSE; + } + +#if LIBULTRA_VERSION < OS_VER_J + if (__osAiDeviceBusy()) { + return -1; + } +#endif + + IO_WRITE(AI_DRAM_ADDR_REG, osVirtualToPhysical(bptr)); + IO_WRITE(AI_LEN_REG, size); + return 0; +} diff --git a/lib/ultra/io/cartrominit.c b/lib/ultra/io/cartrominit.c new file mode 100644 index 00000000..700d9171 --- /dev/null +++ b/lib/ultra/io/cartrominit.c @@ -0,0 +1,100 @@ +#include "PR/os_internal.h" +#include "PR/R4300.h" +#include "PR/rcp.h" +#include "PR/os.h" +#include "piint.h" +#include "macros.h" + +#if LIBULTRA_VERSION >= OS_VER_J +ALIGNED8 OSPiHandle __CartRomHandle; + +OSPiHandle* osCartRomInit(void) { + u32 value = 0; + u32 saveMask; + static int first = 1; + register u32 stat; + u32 latency; + u32 pulse; + u32 pageSize; + u32 relDuration; + + __osPiGetAccess(); + + if (!first) { + __osPiRelAccess(); + return &__CartRomHandle; + } + + first = 0; + __CartRomHandle.type = DEVICE_TYPE_CART; + __CartRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2); + __CartRomHandle.domain = 0; + __CartRomHandle.speed = 0; + bzero(&__CartRomHandle.transferInfo, sizeof(__OSTranxInfo)); + + WAIT_ON_IO_BUSY(stat); + + latency = IO_READ(PI_BSD_DOM1_LAT_REG); + pageSize = IO_READ(PI_BSD_DOM1_PGS_REG); + relDuration = IO_READ(PI_BSD_DOM1_RLS_REG); + pulse = IO_READ(PI_BSD_DOM1_PWD_REG); + + IO_WRITE(PI_BSD_DOM1_LAT_REG, 0xFF); + IO_WRITE(PI_BSD_DOM1_PGS_REG, 0); + IO_WRITE(PI_BSD_DOM1_RLS_REG, 3); + IO_WRITE(PI_BSD_DOM1_PWD_REG, 0xFF); + + value = IO_READ(__CartRomHandle.baseAddress); + __CartRomHandle.latency = value & 0xFF; + __CartRomHandle.pageSize = (value >> 0x10) & 0xF; + __CartRomHandle.relDuration = (value >> 0x14) & 0xF; + __CartRomHandle.pulse = (value >> 8) & 0xFF; + + IO_WRITE(PI_BSD_DOM1_LAT_REG, latency); + IO_WRITE(PI_BSD_DOM1_PGS_REG, pageSize); + IO_WRITE(PI_BSD_DOM1_RLS_REG, relDuration); + IO_WRITE(PI_BSD_DOM1_PWD_REG, pulse); + + saveMask = __osDisableInt(); + __CartRomHandle.next = __osPiTable; + __osPiTable = &__CartRomHandle; + __osRestoreInt(saveMask); + __osPiRelAccess(); + + return &__CartRomHandle; +} + +#else +ALIGNED8 OSPiHandle CartRomHandle; + +OSPiHandle *osCartRomInit(void) { + u32 domain = 0; + u32 saveMask; + + if (CartRomHandle.baseAddress == PHYS_TO_K1(PI_DOM1_ADDR2)) { + return &CartRomHandle; + } + + CartRomHandle.type = DEVICE_TYPE_CART; + CartRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2); + osPiRawReadIo(0, &domain); + CartRomHandle.latency = domain & 0xff; + CartRomHandle.pulse = (domain >> 8) & 0xff; + CartRomHandle.pageSize = (domain >> 0x10) & 0xf; + CartRomHandle.relDuration = (domain >> 0x14) & 0xf; + CartRomHandle.domain = PI_DOMAIN1; +#if LIBULTRA_VERSION >= OS_VER_I + CartRomHandle.speed = 0; +#endif + + bzero(&CartRomHandle.transferInfo, sizeof(__OSTranxInfo)); + + saveMask = __osDisableInt(); + CartRomHandle.next = __osPiTable; + __osPiTable = &CartRomHandle; + __osRestoreInt(saveMask); + + return &CartRomHandle; +} + +#endif diff --git a/lib/ultra/io/conteeplongread.c b/lib/ultra/io/conteeplongread.c new file mode 100644 index 00000000..b5911fbf --- /dev/null +++ b/lib/ultra/io/conteeplongread.c @@ -0,0 +1,24 @@ +#include "PR/os_internal.h" +#include "controller.h" + +s32 osEepromLongRead(OSMesgQueue *mq, u8 address, u8 *buffer, s32 length) { + s32 ret = 0; +#if LIBULTRA_VERSION < OS_VER_I + if (address > EEPROM_MAXBLOCKS) { + return CONT_RANGE_ERROR; + } +#endif + + while (length > 0) { + ERRCK(osEepromRead(mq, address, buffer)); + length -= EEPROM_BLOCK_SIZE; + address++; + buffer += EEPROM_BLOCK_SIZE; +#if LIBULTRA_VERSION < OS_VER_I + osSetTimer(&__osEepromTimer, OS_USEC_TO_CYCLES(12000), 0, &__osEepromTimerQ, &__osEepromTimerMsg); + osRecvMesg(&__osEepromTimerQ, NULL, OS_MESG_BLOCK); +#endif + } + + return ret; +} diff --git a/lib/ultra/io/conteeplongwrite.c b/lib/ultra/io/conteeplongwrite.c new file mode 100644 index 00000000..acc3074d --- /dev/null +++ b/lib/ultra/io/conteeplongwrite.c @@ -0,0 +1,22 @@ +#include "PR/os_internal.h" +#include "controller.h" + +s32 osEepromLongWrite(OSMesgQueue *mq, u8 address, u8 *buffer, int length) { + s32 ret = 0; +#if LIBULTRA_VERSION < OS_VER_I + if (address > EEPROM_MAXBLOCKS) { + return CONT_RANGE_ERROR; + } +#endif + + while (length > 0) { + ERRCK(osEepromWrite(mq, address, buffer)); + length -= EEPROM_BLOCK_SIZE; + address++; + buffer += EEPROM_BLOCK_SIZE; + osSetTimer(&__osEepromTimer, OS_USEC_TO_CYCLES(12000), 0, &__osEepromTimerQ, &__osEepromTimerMsg); + osRecvMesg(&__osEepromTimerQ, NULL, OS_MESG_BLOCK); + } + + return ret; +} diff --git a/lib/ultra/io/conteepprobe.c b/lib/ultra/io/conteepprobe.c new file mode 100644 index 00000000..3512661f --- /dev/null +++ b/lib/ultra/io/conteepprobe.c @@ -0,0 +1,65 @@ +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#ifdef BBPLAYER +s32 osEepromProbe(UNUSED OSMesgQueue *mq) { + s32 ret = 0; + + __osSiGetAccess(); + + if (__osBbEepromSize == EEPROM_SIZE) { + ret = EEPROM_TYPE_4K; + } else if (__osBbEepromSize == EEP16K_SIZE) { + ret = EEPROM_TYPE_16K; + } + + __osSiRelAccess(); + return ret; +} + +#else +s32 osEepromProbe(OSMesgQueue *mq) { + s32 ret = 0; +#if LIBULTRA_VERSION > OS_VER_H + u16 type; +#endif + OSContStatus sdata; + + __osSiGetAccess(); + +#if LIBULTRA_VERSION > OS_VER_H + ret = __osEepStatus(mq, &sdata); + type = sdata.type & (CONT_EEPROM | CONT_EEP16K); + + if (ret != 0) { + ret = 0; + } else { + switch (type) { + case CONT_EEPROM: + ret = EEPROM_TYPE_4K; + break; + case CONT_EEPROM | CONT_EEP16K: + ret = EEPROM_TYPE_16K; + break; + default: + ret = 0; + break; + } + } + +#if BUILD_VERSION >= OS_VER_L + __osEepromRead16K = 0; +#endif +#else + ret = __osEepStatus(mq, &sdata); + ret = (ret == 0 && (sdata.type & CONT_EEPROM)) ? EEPROM_TYPE_4K : 0; +#endif + + __osSiRelAccess(); + return ret; +} +#endif diff --git a/lib/ultra/io/conteepread.c b/lib/ultra/io/conteepread.c new file mode 100644 index 00000000..a82619ab --- /dev/null +++ b/lib/ultra/io/conteepread.c @@ -0,0 +1,174 @@ +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#if LIBULTRA_VERSION > OS_VER_H +ALIGNED16 OSPifRam __osEepPifRam; +#if LIBULTRA_VERSION >= OS_VER_L +s32 __osEepromRead16K; +#endif +#endif + +#ifdef BBPLAYER + +s32 osEepromRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer) { + s32 ret = 0; + + __osSiGetAccess(); + + if (__osBbEepromSize == EEPROM_SIZE) { + if (address >= EEPROM_MAXBLOCKS) { + ret = CONT_RANGE_ERROR; + } + } else if (__osBbEepromSize != EEP16K_SIZE) { + ret = CONT_NO_RESPONSE_ERROR; + } + + if (ret == 0) { + int i; + for (i = 0; i < EEPROM_BLOCK_SIZE; i++) { + buffer[i] = (__osBbEepromAddress + address * EEPROM_BLOCK_SIZE)[i]; + } + } + + __osSiRelAccess(); + return ret; +} + +#else +static void __osPackEepReadData(u8); + +s32 osEepromRead(OSMesgQueue *mq, u8 address, u8 *buffer) { + s32 ret = 0; + s32 i = 0; +#if LIBULTRA_VERSION > OS_VER_H + u16 type; +#endif + u8 *ptr = (u8 *) &__osEepPifRam.ramarray; + OSContStatus sdata; + __OSContEepromFormat eepromformat; + +#if LIBULTRA_VERSION < OS_VER_I + if (address > EEPROM_MAXBLOCKS) { + return CONT_RANGE_ERROR; + } +#endif + + __osSiGetAccess(); + ret = __osEepStatus(mq, &sdata); + +#if LIBULTRA_VERSION > OS_VER_H + type = sdata.type & (CONT_EEPROM | CONT_EEP16K); + +#if LIBULTRA_VERSION < OS_VER_J + if (ret != 0) { + __osSiRelAccess(); + return CONT_NO_RESPONSE_ERROR; + } +#else + if (ret == 0) { +#endif + switch (type) { + case CONT_EEPROM: + CONT_CHECK_BLOCK(address, EEPROM_MAXBLOCKS, CONT_RANGE_ERROR); + break; + case CONT_EEPROM | CONT_EEP16K: + // error not technically possible + CONT_CHECK_BLOCK(address, EEP16K_MAXBLOCKS, CONT_RANGE_ERROR) +#if LIBULTRA_VERSION >= OS_VER_L + else { + __osEepromRead16K = 1; + } +#endif + break; + default: +#if LIBULTRA_VERSION < OS_VER_J + __osSiRelAccess(); + return CONT_NO_RESPONSE_ERROR; +#else + ret = CONT_NO_RESPONSE_ERROR; +#endif + } +#if LIBULTRA_VERSION >= OS_VER_J + } + + if (ret != 0) { + __osSiRelAccess(); + return ret; + } +#endif + +#else + if (ret != 0 || sdata.type != CONT_EEPROM) { + return CONT_NO_RESPONSE_ERROR; + } +#endif + + while (sdata.status & CONT_EEPROM_BUSY) { + __osEepStatus(mq, &sdata); + } + __osPackEepReadData(address); + + ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); // send command to pif + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + +#if LIBULTRA_VERSION < OS_VER_I + CONT_PIFRAM_SET(__osEepPifRam, CONT_CMD_NOP, 0); +#endif + + ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); //recv response + __osContLastCmd = CONT_CMD_READ_EEPROM; + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + for (i = 0; i < MAXCONTROLLERS; i++) { + ptr++; + } + + eepromformat = *(__OSContEepromFormat *) ptr; + ret = CHNL_ERR(eepromformat); + + if (ret == 0) { + for (i = 0; i < ARRAY_COUNT(eepromformat.data); i++) { + *buffer++ = eepromformat.data[i]; + } + } + + __osSiRelAccess(); + return ret; +} + +void __osPackEepReadData(u8 address) { + u8 *ptr = (u8 *) &__osEepPifRam.ramarray; + __OSContEepromFormat eepromformat; + s32 i; + +#if LIBULTRA_VERSION >= OS_VER_J + __osEepPifRam.pifstatus = CONT_CMD_EXE; +#else + CONT_PIFRAM_SET(__osEepPifRam, CONT_CMD_NOP, CONT_CMD_EXE); +#endif + + eepromformat.txsize = CONT_CMD_READ_EEPROM_TX; + eepromformat.rxsize = CONT_CMD_READ_EEPROM_RX; + eepromformat.cmd = CONT_CMD_READ_EEPROM; + eepromformat.address = address; + +#if LIBULTRA_VERSION < OS_VER_J + for (i = 0; i < ARRAY_COUNT(eepromformat.data); i++) { + eepromformat.data[i] = 0; + } +#endif + + for (i = 0; i < MAXCONTROLLERS; i++) { + *ptr++ = 0; + } + + *(__OSContEepromFormat *) ptr = eepromformat; + ptr += sizeof(__OSContEepromFormat); + *ptr = CONT_CMD_END; +} + +#endif diff --git a/lib/src/osEepromWrite.c b/lib/ultra/io/conteepwrite.c similarity index 51% rename from lib/src/osEepromWrite.c rename to lib/ultra/io/conteepwrite.c index 68069b1b..f2d0f033 100644 --- a/lib/src/osEepromWrite.c +++ b/lib/ultra/io/conteepwrite.c @@ -1,10 +1,15 @@ -#include "libultra_internal.h" -#include "osContInternal.h" -#include "PR/ique.h" +#include "PR/os_internal.h" #include "controller.h" #include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif -#ifdef VERSION_CN +#if LIBULTRA_VERSION < OS_VER_I +ALIGNED16 OSPifRam __osEepPifRam; +#endif + +#ifdef BBPLAYER s32 osEepromWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer) { s32 ret = 0; @@ -12,17 +17,17 @@ s32 osEepromWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer) { __osSiGetAccess(); - if (__osBbEepromSize == 0x200) { - if (address >= 0x200 / 8) { - ret = -1; + if (__osBbEepromSize == EEPROM_SIZE) { + if (address >= EEPROM_MAXBLOCKS) { + ret = CONT_RANGE_ERROR; } - } else if (__osBbEepromSize != 0x800) { - ret = 8; + } else if (__osBbEepromSize != EEP16K_SIZE) { + ret = CONT_NO_RESPONSE_ERROR; } if (ret == 0) { - for (i = 0; i < 8; i++) { - (__osBbEepromAddress + address * 8)[i] = buffer[i]; + for (i = 0; i < EEPROM_BLOCK_SIZE; i++) { + (__osBbEepromAddress + address * EEPROM_BLOCK_SIZE)[i] = buffer[i]; } } @@ -31,28 +36,81 @@ s32 osEepromWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer) { } #else - -OSPifRam __osEepPifRam; - void __osPackEepWriteData(u8, u8 *); s32 osEepromWrite(OSMesgQueue *mq, u8 address, u8 *buffer) { s32 ret = 0; +#if LIBULTRA_VERSION < OS_VER_J s32 i; +#endif +#if LIBULTRA_VERSION > OS_VER_H + u16 type; +#endif u8 *ptr = (u8 *) &__osEepPifRam.ramarray; __OSContEepromFormat eepromformat; OSContStatus sdata; +#if LIBULTRA_VERSION > OS_VER_K + u8 temp[EEPROM_BLOCK_SIZE]; +#endif +#if LIBULTRA_VERSION < OS_VER_I if (address > EEPROM_MAXBLOCKS) { - return -1; + return CONT_RANGE_ERROR; } +#endif __osSiGetAccess(); ret = __osEepStatus(mq, &sdata); +#if LIBULTRA_VERSION > OS_VER_H + type = sdata.type & (CONT_EEPROM | CONT_EEP16K); + +#if LIBULTRA_VERSION < OS_VER_J + if (ret != 0) { + __osSiRelAccess(); + return CONT_NO_RESPONSE_ERROR; + } +#else + if (ret == 0) { +#endif + switch (type) { + case CONT_EEPROM: + CONT_CHECK_BLOCK(address, EEPROM_MAXBLOCKS, CONT_RANGE_ERROR); + break; + case CONT_EEPROM | CONT_EEP16K: + // error not technically possible + CONT_CHECK_BLOCK(address, EEP16K_MAXBLOCKS, CONT_RANGE_ERROR) +#if LIBULTRA_VERSION >= OS_VER_L + else if (__osEepromRead16K) { + __osEepromRead16K = 0; + __osSiRelAccess(); + osEepromRead(mq, (address ^ 1), temp); + __osSiGetAccess(); + } +#endif + break; + default: +#if LIBULTRA_VERSION < OS_VER_J + __osSiRelAccess(); + return CONT_NO_RESPONSE_ERROR; +#else + ret = CONT_NO_RESPONSE_ERROR; +#endif + } +#if LIBULTRA_VERSION >= OS_VER_J + } + + if (ret != 0) { + __osSiRelAccess(); + return ret; + } +#endif + +#else if (ret != 0 || sdata.type != CONT_EEPROM) { return CONT_NO_RESPONSE_ERROR; } +#endif while (sdata.status & CONT_EEPROM_BUSY) { __osEepStatus(mq, &sdata); @@ -60,24 +118,28 @@ s32 osEepromWrite(OSMesgQueue *mq, u8 address, u8 *buffer) { __osPackEepWriteData(address, buffer); - ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); + ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); // send command to pif osRecvMesg(mq, NULL, OS_MESG_BLOCK); - for (i = 0; i < ARRAY_COUNT(__osEepPifRam.ramarray) + 1; i++) { - __osEepPifRam.ramarray[i] = CONT_CMD_NOP; - } +#if LIBULTRA_VERSION < OS_VER_I + CONT_PIFRAM_SET(__osEepPifRam, CONT_CMD_NOP, 0); +#endif - __osEepPifRam.pifstatus = 0; - ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); + ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); //recv response __osContLastCmd = CONT_CMD_WRITE_EEPROM; osRecvMesg(mq, NULL, OS_MESG_BLOCK); - for (i = 0; i < 4; i++) { +#if LIBULTRA_VERSION >= OS_VER_J + ptr += MAXCONTROLLERS; +#else + for (i = 0; i < MAXCONTROLLERS; i++) { ptr++; } +#endif eepromformat = *(__OSContEepromFormat *) ptr; ret = CHNL_ERR(eepromformat); + __osSiRelAccess(); return ret; } @@ -87,10 +149,11 @@ void __osPackEepWriteData(u8 address, u8 *buffer) { __OSContEepromFormat eepromformat; s32 i; - for (i = 0; i < ARRAY_COUNT(__osEepPifRam.ramarray) + 1; i++) { - __osEepPifRam.ramarray[i] = CONT_CMD_NOP; - } +#if LIBULTRA_VERSION >= OS_VER_J __osEepPifRam.pifstatus = CONT_CMD_EXE; +#else + CONT_PIFRAM_SET(__osEepPifRam, CONT_CMD_NOP, CONT_CMD_EXE); +#endif eepromformat.txsize = CONT_CMD_WRITE_EEPROM_TX; eepromformat.rxsize = CONT_CMD_WRITE_EEPROM_RX; @@ -101,9 +164,10 @@ void __osPackEepWriteData(u8 address, u8 *buffer) { eepromformat.data[i] = *buffer++; } - for (i = 0; i < 4; i++) { + for (i = 0; i < MAXCONTROLLERS; i++) { *ptr++ = 0; } + *(__OSContEepromFormat *) ptr = eepromformat; ptr += sizeof(__OSContEepromFormat); *ptr = CONT_CMD_END; @@ -115,13 +179,11 @@ s32 __osEepStatus(OSMesgQueue *mq, OSContStatus *data) { u8 *ptr = (u8 *) __osEepPifRam.ramarray; __OSContRequesFormat requestformat; - for (i = 0; i < ARRAY_COUNT(__osEepPifRam.ramarray) + 1; i++) { - __osEepPifRam.ramarray[i] = 0; - } - __osEepPifRam.pifstatus = CONT_CMD_EXE; + CONT_PIFRAM_SET(__osEepPifRam, 0, CONT_CMD_EXE); ptr = (u8 *) __osEepPifRam.ramarray; - for (i = 0; i < 4; i++) { + + for (i = 0; i < MAXCONTROLLERS; i++) { *ptr++ = 0; } @@ -133,15 +195,21 @@ s32 __osEepStatus(OSMesgQueue *mq, OSContStatus *data) { requestformat.typel = CONT_CMD_NOP; requestformat.status = CONT_CMD_NOP; requestformat.dummy1 = CONT_CMD_NOP; - *(__OSContRequesFormat *) ptr = requestformat; + *REQFORMAT(ptr) = requestformat; ptr += sizeof(__OSContRequesFormat); *ptr = CONT_CMD_END; ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); +#if LIBULTRA_VERSION >= OS_VER_J + __osContLastCmd = CONT_CMD_END; +#elif LIBULTRA_VERSION >= OS_VER_I + __osContLastCmd = CONT_CMD_REQUEST_STATUS; +#else __osContLastCmd = CONT_CMD_WRITE_EEPROM; +#endif ret = __osSiRawStartDma(OS_READ, &__osEepPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); @@ -150,18 +218,22 @@ s32 __osEepStatus(OSMesgQueue *mq, OSContStatus *data) { return ret; } - ptr = (u8 *) __osEepPifRam.ramarray; - for (i = 0; i < 4; i++) { + ptr = (u8 *) &__osEepPifRam; + + for (i = 0; i < MAXCONTROLLERS; i++) { *ptr++ = 0; } - requestformat = *(__OSContRequesFormat *) ptr; + requestformat = *REQFORMAT(ptr); + data->errnum = CHNL_ERR(requestformat); data->type = (requestformat.typel << 8) | requestformat.typeh; data->status = requestformat.status; + if (data->errnum != 0) { return data->errnum; } + return 0; } diff --git a/lib/ultra/io/contramread.c b/lib/ultra/io/contramread.c new file mode 100644 index 00000000..eba6d382 --- /dev/null +++ b/lib/ultra/io/contramread.c @@ -0,0 +1,186 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#ifdef BBPLAYER +s32 __osContRamRead(UNUSED OSMesgQueue* mq, int channel, u16 address, u8* buffer) { + s32 ret; + + __osSiGetAccess(); + + ret = 0; + if (__osBbPakAddress[channel] != 0) { + if (__osBbPakSize - 0x20 >= address * 0x20) { + int i; + + for (i = 0; i < 0x20; i++) { + buffer[i] = (__osBbPakAddress[channel] + address * 0x20)[i]; + } + } + } else { + ret = 1; + } + + __osSiRelAccess(); + + return ret; +} +#else + +#if LIBULTRA_VERSION >= OS_VER_J +s32 __osPfsLastChannel = -1; + +s32 __osContRamRead(OSMesgQueue* mq, int channel, u16 address, u8* buffer) { + s32 ret; + s32 i; + u8* ptr; + s32 retry = 2; + + __osSiGetAccess(); + + do { + ptr = (u8*)&__osPfsPifRam; + + if (__osContLastCmd != CONT_CMD_READ_PAK || __osPfsLastChannel != channel) { + __osContLastCmd = CONT_CMD_READ_PAK; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++) { + *ptr++ = CONT_CMD_REQUEST_STATUS; + } + + __osPfsPifRam.pifstatus = CONT_CMD_EXE; + + READFORMAT(ptr)->dummy = CONT_CMD_NOP; + READFORMAT(ptr)->txsize = CONT_CMD_READ_PAK_TX; + READFORMAT(ptr)->rxsize = CONT_CMD_READ_PAK_RX; + READFORMAT(ptr)->cmd = CONT_CMD_READ_PAK; + READFORMAT(ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END; + } else { + ptr += channel; + } + + CONT_READFORMAT_ADDR(READFORMAT(ptr), address); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + ret = CHNL_ERR(*READFORMAT(ptr)); + + if (!ret) { + if (__osContDataCrc(READFORMAT(ptr)->data) != READFORMAT(ptr)->datacrc) { + ret = __osPfsGetStatus(mq, channel); + + if (ret) { + break; + } else { + ret = PFS_ERR_CONTRFAIL; + } + } else { + bcopy(&READFORMAT(ptr)->data, buffer, BLOCKSIZE); + } + } else { + ret = PFS_ERR_NOPACK; + } + } while ((ret == PFS_ERR_CONTRFAIL) && (retry-- >= 0)); + __osSiRelAccess(); + + return ret; +} +#else +void __osPackRamReadData(int channel, u16 address); + +s32 __osContRamRead(OSMesgQueue *mq, int channel, u16 address, u8 *buffer) { + s32 ret = 0; + int i; + u8 *ptr = (u8 *)&__osPfsPifRam; + __OSContRamReadFormat ramreadformat; + int retry = 2; + + __osSiGetAccess(); + __osContLastCmd = CONT_CMD_READ_PAK; + __osPackRamReadData(channel, address); + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + do { + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + ptr = (u8 *)&__osPfsPifRam; + if (channel != 0) { + for (i = 0; i < channel; i++) { + ptr++; + } + } + + ramreadformat = *READFORMAT(ptr); + + ret = CHNL_ERR(ramreadformat); + if (ret == 0) { + u8 c; + c = __osContDataCrc((u8*)&ramreadformat.data); + if (c != ramreadformat.datacrc) { + ret = __osPfsGetStatus(mq, channel); + + if (ret != 0) { + __osSiRelAccess(); + return ret; + } + + ret = PFS_ERR_CONTRFAIL; + } else { + for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { + *buffer++ = ramreadformat.data[i]; + } + } + } else { + ret = PFS_ERR_NOPACK; + } + } while ((ret == PFS_ERR_CONTRFAIL) && retry-- >= 0); + + __osSiRelAccess(); + return ret; +} + +void __osPackRamReadData(int channel, u16 address) { + u8 *ptr; + __OSContRamReadFormat ramreadformat; + int i; + + ptr = (u8 *)__osPfsPifRam.ramarray; + + CONT_PIFRAM_SET(__osPfsPifRam, 0, CONT_CMD_EXE); + + ramreadformat.dummy = CONT_CMD_NOP; + ramreadformat.txsize = CONT_CMD_READ_PAK_TX; + ramreadformat.rxsize = CONT_CMD_READ_PAK_RX; + ramreadformat.cmd = CONT_CMD_READ_PAK; + CONT_READFORMAT_ADDR(ramreadformat, address); + ramreadformat.datacrc = CONT_CMD_NOP; + for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { + ramreadformat.data[i] = CONT_CMD_NOP; + } + + if (channel != 0) { + for (i = 0; i < channel; i++) { + *ptr++ = 0; + } + } + + *READFORMAT(ptr) = ramreadformat; + ptr += sizeof(__OSContRamReadFormat); + ptr[0] = CONT_CMD_END; +} +#endif + +#endif diff --git a/lib/ultra/io/contramwrite.c b/lib/ultra/io/contramwrite.c new file mode 100644 index 00000000..987fc616 --- /dev/null +++ b/lib/ultra/io/contramwrite.c @@ -0,0 +1,189 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#ifdef BBPLAYER +s32 __osContRamWrite(UNUSED OSMesgQueue *mq, int channel, u16 address, u8 *buffer, s32 force) { + s32 ret = 0; + + if ((force != TRUE) && (address < PFS_LABEL_AREA) && (address != 0)) { + return 0; + } + + __osSiGetAccess(); + + if (__osBbPakAddress[channel] != 0) { + if (__osBbPakSize - 0x20 >= address * 0x20) { + int i = 0; + + for (i = 0; i < 0x20; i++) { + (__osBbPakAddress[channel] + address * 0x20)[i] = buffer[i]; + } + } + } else { + ret = 1; + } + + __osSiRelAccess(); + return ret; +} +#else + +#if LIBULTRA_VERSION >= OS_VER_J +s32 __osContRamWrite(OSMesgQueue* mq, int channel, u16 address, u8* buffer, int force) { + s32 ret = 0; + s32 i; + u8* ptr; + s32 retry = 2; + u8 crc; + + if ((force != TRUE) && (address < PFS_LABEL_AREA) && (address != 0)) { + return 0; + } + + __osSiGetAccess(); + + do { + ptr = (u8 *) __osPfsPifRam.ramarray; + + if (__osContLastCmd != CONT_CMD_WRITE_PAK || __osPfsLastChannel != channel) { + __osContLastCmd = CONT_CMD_WRITE_PAK; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++) { + *ptr++ = CONT_CMD_REQUEST_STATUS; + } + + __osPfsPifRam.pifstatus = CONT_CMD_EXE; + + READFORMAT(ptr)->dummy = CONT_CMD_NOP; + READFORMAT(ptr)->txsize = CONT_CMD_WRITE_PAK_TX; + READFORMAT(ptr)->rxsize = CONT_CMD_WRITE_PAK_RX; + READFORMAT(ptr)->cmd = CONT_CMD_WRITE_PAK; + READFORMAT(ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END; + } else { + ptr += channel; + } + + CONT_READFORMAT_ADDR(READFORMAT(ptr), address); + + bcopy(buffer, READFORMAT(ptr)->data, BLOCKSIZE); + + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + crc = __osContDataCrc(buffer); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + ret = CHNL_ERR(*READFORMAT(ptr)); + + if (!ret) { + if (crc != READFORMAT(ptr)->datacrc) { + if ((ret = __osPfsGetStatus(mq, channel))) { + break; + } else { + ret = PFS_ERR_CONTRFAIL; + } + } + } else { + ret = PFS_ERR_NOPACK; + } + } while ((ret == PFS_ERR_CONTRFAIL) && (retry-- >= 0)); + + __osSiRelAccess(); + + return ret; +} +#else +extern s32 __osPfsGetStatus(OSMesgQueue *, s32); +void __osPackRamWriteData(s32 channel, u16 address, u8 *buffer); + +s32 __osContRamWrite(OSMesgQueue *mq, int channel, u16 address, u8 *buffer, s32 force) { + s32 ret = 0; + s32 i; + u8* ptr = (u8*)&__osPfsPifRam; + __OSContRamReadFormat ramreadformat; + s32 retry = 2; + + if (force != TRUE && address < PFS_LABEL_AREA && address != 0) { + return 0; + } + __osSiGetAccess(); + __osContLastCmd = CONT_CMD_WRITE_PAK; + __osPackRamWriteData(channel, address, buffer); + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + do { + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + ptr = (u8 *)&__osPfsPifRam; + + if (channel != 0) { + for (i = 0; i < channel; i++) { + ptr++; + } + } + + ramreadformat = *READFORMAT(ptr); + + ret = CHNL_ERR(ramreadformat); + if (ret == 0) { + if (__osContDataCrc(buffer) != ramreadformat.datacrc) { + ret = __osPfsGetStatus(mq, channel); + + if (ret != 0) { + __osSiRelAccess(); + return ret; + } + + ret = PFS_ERR_CONTRFAIL; + } + } else { + ret = PFS_ERR_NOPACK; + } + } while ((ret == PFS_ERR_CONTRFAIL) && retry-- >= 0); + + __osSiRelAccess(); + return ret; +} + +void __osPackRamWriteData(int channel, u16 address, u8 *buffer) { + u8 *ptr; + __OSContRamReadFormat ramreadformat; + int i; + + ptr = (u8 *) __osPfsPifRam.ramarray; + + CONT_PIFRAM_SET(__osPfsPifRam, 0, CONT_CMD_EXE); + + ramreadformat.dummy = CONT_CMD_NOP; + ramreadformat.txsize = CONT_CMD_WRITE_PAK_TX; + ramreadformat.rxsize = CONT_CMD_WRITE_PAK_RX; + ramreadformat.cmd = CONT_CMD_WRITE_PAK; + CONT_READFORMAT_ADDR(ramreadformat, address); + ramreadformat.datacrc = CONT_CMD_NOP; + for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { + ramreadformat.data[i] = *buffer++; + } + + if (channel != 0) { + for (i = 0; i < channel; i++) { + *ptr++ = 0; + } + } + + *READFORMAT(ptr) = ramreadformat; + ptr += sizeof(__OSContRamReadFormat); + ptr[0] = CONT_CMD_END; +} +#endif + +#endif diff --git a/lib/ultra/io/contreaddata.c b/lib/ultra/io/contreaddata.c new file mode 100644 index 00000000..b89e8942 --- /dev/null +++ b/lib/ultra/io/contreaddata.c @@ -0,0 +1,90 @@ +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +void __osPackReadData(void); + +s32 osContStartReadData(OSMesgQueue *mesg) { + s32 ret = 0; +#if LIBULTRA_VERSION < OS_VER_I + s32 i; +#endif + + __osSiGetAccess(); + + if (__osContLastCmd != CONT_CMD_READ_BUTTON) { + __osPackReadData(); + ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray); + osRecvMesg(mesg, NULL, OS_MESG_BLOCK); + } + +#if LIBULTRA_VERSION < OS_VER_I + CONT_PIFRAM_SET(__osContPifRam, CONT_CMD_NOP, 0); +#endif + + ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray); +#ifdef BBPLAYER + __osContLastCmd = CONT_CMD_CHANNEL_RESET; +#else + __osContLastCmd = CONT_CMD_READ_BUTTON; +#endif + + __osSiRelAccess(); + + return ret; +} + +void osContGetReadData(OSContPad *data) { + u8 *ptr = (u8 *) __osContPifRam.ramarray; + __OSContReadFormat readformat; + s32 i; + + for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(readformat), data++) { + readformat = * (__OSContReadFormat *) ptr; + data->errnum = CHNL_ERR(readformat); + + if (data->errnum != 0) { + continue; + } + + data->button = readformat.button; + data->stick_x = readformat.stick_x; + data->stick_y = readformat.stick_y; + } + +#ifdef BBPLAYER + if (__osBbIsBb && __osBbHackFlags != 0) { + OSContPad tmp; + data -= __osMaxControllers; + + tmp = *data; + *data = data[__osBbHackFlags]; + data[__osBbHackFlags] = tmp; + } +#endif +} + +void __osPackReadData() { + u8 *ptr = (u8 *) __osContPifRam.ramarray; + __OSContReadFormat readformat; + s32 i; + + CONT_PIFRAM_SET(__osContPifRam, 0, CONT_CMD_EXE); + + readformat.dummy = CONT_CMD_NOP; + readformat.txsize = CONT_CMD_READ_BUTTON_TX; + readformat.rxsize = CONT_CMD_READ_BUTTON_RX; + readformat.cmd = CONT_CMD_READ_BUTTON; + readformat.button = 0xFFFF; + readformat.stick_x = -1; + readformat.stick_y = -1; + + for (i = 0; i < __osMaxControllers; i++) { + * (__OSContReadFormat *) ptr = readformat; + ptr += sizeof(readformat); + } + *ptr = CONT_CMD_END; +} diff --git a/lib/ultra/io/controller.c b/lib/ultra/io/controller.c new file mode 100644 index 00000000..f21a9c75 --- /dev/null +++ b/lib/ultra/io/controller.c @@ -0,0 +1,125 @@ +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#if LIBULTRA_VERSION > OS_VER_D +#define CONT_CMD_REQ CONT_CMD_REQUEST_STATUS +#else +#define CONT_CMD_REQ CONT_CMD_RESET +#endif + +u32 _osContInitialized = 0; + +ALIGNED16 OSPifRam __osContPifRam; +u8 __osContLastCmd; +u8 __osMaxControllers; + +OSTimer __osEepromTimer; +ALIGNED8 OSMesgQueue __osEepromTimerQ; +OSMesg __osEepromTimerMsg; + +s32 osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *data) { + OSMesg dummy; + u32 ret = 0; + OSTime t; + OSTimer mytimer; + OSMesgQueue timerMesgQueue; + + if (_osContInitialized) { + return 0; + } + _osContInitialized = 1; + + t = osGetTime(); + if (t < OS_USEC_TO_CYCLES(500000)) { + osCreateMesgQueue(&timerMesgQueue, &dummy, 1); + osSetTimer(&mytimer, OS_USEC_TO_CYCLES(500000) - t, 0, &timerMesgQueue, &dummy); + osRecvMesg(&timerMesgQueue, &dummy, OS_MESG_BLOCK); + } + + __osMaxControllers = MAXCONTROLLERS; + + __osPackRequestData(CONT_CMD_REQ); + + ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); + + __osContGetInitData(bitpattern, data); +#ifdef BBPLAYER + __osContLastCmd = CONT_CMD_CHANNEL_RESET; +#else + __osContLastCmd = CONT_CMD_REQ; +#endif + __osSiCreateAccessQueue(); + osCreateMesgQueue(&__osEepromTimerQ, &__osEepromTimerMsg, 1); + + return ret; +} + +void __osContGetInitData(u8 *pattern, OSContStatus *data) { + u8 *ptr; + __OSContRequesFormat response; + s32 i; + u8 bits; + + bits = 0; + ptr = (u8 *) __osContPifRam.ramarray; + for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(response), data++) { + response = *REQFORMAT(ptr); + data->errnum = CHNL_ERR(response); + if (data->errnum == 0) { + data->type = response.typel << 8 | response.typeh; +#ifdef BBPLAYER + data->status = __osBbPakAddress[i] != NULL; +#else + data->status = response.status; +#endif + + bits |= 1 << i; + } + } +#ifdef BBPLAYER + if (__osBbIsBb && __osBbHackFlags != 0) { + OSContStatus tmp; + bits = (bits & ~((1 << __osBbHackFlags) | 1)) | + ((bits & 1) << __osBbHackFlags) | + ((bits & (1 << __osBbHackFlags)) >> __osBbHackFlags); + data -= __osMaxControllers; + tmp = *data; + *data = data[__osBbHackFlags]; + data[__osBbHackFlags] = tmp; + } +#endif + + *pattern = bits; +} + +void __osPackRequestData(u8 cmd) { + u8 *ptr; + __OSContRequesFormat requestHeader; + s32 i; + + CONT_PIFRAM_SET(__osContPifRam, 0, CONT_CMD_EXE); + + ptr = (u8 *) __osContPifRam.ramarray; + requestHeader.dummy = CONT_CMD_NOP; + requestHeader.txsize = CONT_CMD_RESET_TX; + requestHeader.rxsize = CONT_CMD_RESET_RX; + requestHeader.cmd = cmd; + requestHeader.typeh = CONT_CMD_NOP; + requestHeader.typel = CONT_CMD_NOP; + requestHeader.status = CONT_CMD_NOP; + requestHeader.dummy1 = CONT_CMD_NOP; + + for (i = 0; i < __osMaxControllers; i++) { + *REQFORMAT(ptr) = requestHeader; + ptr += sizeof(requestHeader); + } + *ptr = CONT_CMD_END; +} diff --git a/lib/ultra/io/controller.h b/lib/ultra/io/controller.h new file mode 100644 index 00000000..3d275980 --- /dev/null +++ b/lib/ultra/io/controller.h @@ -0,0 +1,308 @@ +#ifndef _CONTROLLER_H +#define _CONTROLLER_H +#include "PR/os_internal.h" +#include "PR/os.h" +#include "PR/rcp.h" + +//should go somewhere else but +#define ARRLEN(x) ((s32)(sizeof(x) / sizeof(x[0]))) +#define CHNL_ERR(format) (((format).rxsize & CHNL_ERR_MASK) >> 4) + +typedef struct { + /* 0x00 */ u32 ramarray[15]; + /* 0x3C */ u32 pifstatus; +} OSPifRam; + +typedef struct { + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; + /* 0x4 */ u16 button; + /* 0x6 */ s8 stick_x; + /* 0x7 */ s8 stick_y; +} __OSContReadFormat; + +typedef struct { + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; + /* 0x4 */ u8 typeh; + /* 0x5 */ u8 typel; + /* 0x6 */ u8 status; + /* 0x7 */ u8 dummy1; +} __OSContRequesFormat; + +typedef struct { + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; +#if LIBULTRA_VERSION >= OS_VER_J + /* 0x4 */ u8 addrh; + /* 0x5 */ u8 addrl; +#else + /* 0x4 */ u16 address; +#endif + /* 0x6 */ u8 data[BLOCKSIZE]; + /* 0x26 */ u8 datacrc; +} __OSContRamReadFormat; + +typedef union { + /* 0x0 */ struct + { + /* 0x0 */ u8 bank; + /* 0x1 */ u8 page; + } inode_t; + /* 0x0 */ u16 ipage; +} __OSInodeUnit; + +typedef struct { + /* 0x0 */ u32 game_code; + /* 0x4 */ u16 company_code; + /* 0x6 */ __OSInodeUnit start_page; + /* 0x8 */ u8 status; + /* 0x9 */ s8 reserved; + /* 0xA */ u16 data_sum; + /* 0xC */ u8 ext_name[PFS_FILE_EXT_LEN]; + /* 0x10 */ u8 game_name[PFS_FILE_NAME_LEN]; +} __OSDir; + +typedef struct { + /* 0x0 */ __OSInodeUnit inode_page[128]; +} __OSInode; + +typedef struct { + /* 0x0 */ u32 repaired; + /* 0x4 */ u32 random; + /* 0x8 */ u64 serial_mid; + /* 0x10 */ u64 serial_low; + /* 0x18 */ u16 deviceid; + /* 0x1A */ u8 banks; + /* 0x1B */ u8 version; + /* 0x1C */ u16 checksum; + /* 0x1E */ u16 inverted_checksum; +} __OSPackId; + +typedef struct { + /* 0x0 */ u8 txsize; + /* 0x1 */ u8 rxsize; + /* 0x2 */ u8 cmd; + /* 0x3 */ u8 address; + /* 0x4 */ u8 data[EEPROM_BLOCK_SIZE]; +} __OSContEepromFormat; + +// Joybus commands +//from: http://en64.shoutwiki.com/wiki/SI_Registers_Detailed#CONT_CMD_Usage +#define CONT_CMD_REQUEST_STATUS 0 +#define CONT_CMD_READ_BUTTON 1 +#define CONT_CMD_READ_PAK 2 +#define CONT_CMD_WRITE_PAK 3 +#define CONT_CMD_READ_EEPROM 4 +#define CONT_CMD_WRITE_EEPROM 5 +#define CONT_CMD_READ36_VOICE 9 +#define CONT_CMD_WRITE20_VOICE 10 +#define CONT_CMD_READ2_VOICE 11 +#define CONT_CMD_WRITE4_VOICE 12 +#define CONT_CMD_SWRITE_VOICE 13 +#define CONT_CMD_CHANNEL_RESET 0xFD +#define CONT_CMD_RESET 0xFF + +// Bytes transmitted for each joybus command +#define CONT_CMD_REQUEST_STATUS_TX 1 +#define CONT_CMD_READ_BUTTON_TX 1 +#define CONT_CMD_READ_PAK_TX 3 +#define CONT_CMD_WRITE_PAK_TX 35 +#define CONT_CMD_READ_EEPROM_TX 2 +#define CONT_CMD_WRITE_EEPROM_TX 10 +#define CONT_CMD_READ36_VOICE_TX 3 +#define CONT_CMD_WRITE20_VOICE_TX 23 +#define CONT_CMD_READ2_VOICE_TX 3 +#define CONT_CMD_WRITE4_VOICE_TX 7 +#define CONT_CMD_SWRITE_VOICE_TX 3 +#define CONT_CMD_RESET_TX 1 + +// Bytes received for each joybus command +#define CONT_CMD_REQUEST_STATUS_RX 3 +#define CONT_CMD_READ_BUTTON_RX 4 +#define CONT_CMD_READ_PAK_RX 33 +#define CONT_CMD_WRITE_PAK_RX 1 +#define CONT_CMD_READ_EEPROM_RX 8 +#define CONT_CMD_WRITE_EEPROM_RX 1 +#define CONT_CMD_READ36_VOICE_RX 37 +#define CONT_CMD_WRITE20_VOICE_RX 1 +#define CONT_CMD_READ2_VOICE_RX 3 +#define CONT_CMD_WRITE4_VOICE_RX 1 +#define CONT_CMD_SWRITE_VOICE_RX 1 +#define CONT_CMD_RESET_RX 3 + +#define CONT_CMD_NOP 0xff +#define CONT_CMD_END 0xfe //indicates end of a command +#define CONT_CMD_EXE 1 //set pif ram status byte to this to do a command + +#define DIR_STATUS_EMPTY 0 +#define DIR_STATUS_UNKNOWN 1 +#define DIR_STATUS_OCCUPIED 2 + +// Controller accessory addresses +// https://github.com/joeldipops/TransferBoy/blob/master/docs/TransferPakReference.md + +// Accesory detection +#define CONT_ADDR_DETECT 0x8000 +// Rumble +#define CONT_ADDR_RUMBLE 0xC000 +// Controller Pak +// Transfer Pak +#define CONT_ADDR_GB_POWER 0x8000 // Same as the detection address, but semantically different +#define CONT_ADDR_GB_BANK 0xA000 +#define CONT_ADDR_GB_STATUS 0xB000 + +// Addresses sent to controller accessories are in blocks, not bytes +#define CONT_BLOCKS(x) ((x) / BLOCKSIZE) + +// Block addresses of the above +#define CONT_BLOCK_DETECT CONT_BLOCKS(CONT_ADDR_DETECT) +#define CONT_BLOCK_RUMBLE CONT_BLOCKS(CONT_ADDR_RUMBLE) +#define CONT_BLOCK_GB_POWER CONT_BLOCKS(CONT_ADDR_GB_POWER) +#define CONT_BLOCK_GB_BANK CONT_BLOCKS(CONT_ADDR_GB_BANK) +#define CONT_BLOCK_GB_STATUS CONT_BLOCKS(CONT_ADDR_GB_STATUS) + + +// Transfer pak + +#define GB_POWER_ON 0x84 +#define GB_POWER_OFF 0xFE + +typedef struct +{ + /* 0x0 */ __OSInode inode; + /* 0x100 */ u8 bank; + /* 0x101 */ u8 map[PFS_INODE_DIST_MAP]; +} __OSInodeCache; + +extern s32 __osEepStatus(OSMesgQueue *, OSContStatus *); +u16 __osSumcalc(u8 *ptr, int length); +s32 __osIdCheckSum(u16 *ptr, u16 *csum, u16 *icsum); +s32 __osRepairPackId(OSPfs *pfs, __OSPackId *badid, __OSPackId *newid); +s32 __osCheckPackId(OSPfs *pfs, __OSPackId *temp); +s32 __osGetId(OSPfs *pfs); +s32 __osCheckId(OSPfs *pfs); +s32 __osPfsRWInode(OSPfs *pfs, __OSInode *inode, u8 flag, u8 bank); +#if LIBULTRA_VERSION >= OS_VER_J +s32 __osPfsSelectBank(OSPfs *pfs, u8 bank); +#else +s32 __osPfsSelectBank(OSPfs *pfs); +#endif +s32 __osPfsDeclearPage(OSPfs *pfs, __OSInode *inode, int file_size_in_pages, int *first_page, u8 bank, int *decleared, int *last_page); +#if LIBULTRA_VERSION >= OS_VER_J +s32 __osPfsReleasePages(OSPfs *pfs, __OSInode *inode, u8 start_page, u8 bank, __OSInodeUnit *last_page); +#else +s32 __osPfsReleasePages(OSPfs *pfs, __OSInode *inode, u8 start_page, u16 *sum, u8 bank, __OSInodeUnit *last_page, int flag); +#endif +s32 __osBlockSum(OSPfs *pfs, u8 page_no, u16 *sum, u8 bank); +s32 __osContRamRead(OSMesgQueue *mq, int channel, u16 address, u8 *buffer); +s32 __osContRamWrite(OSMesgQueue *mq, s32 channel, u16 address, u8 *buffer, s32 force); +void __osContGetInitData(u8 *pattern, OSContStatus *data); +void __osPackRequestData(u8 cmd); +void __osPfsRequestData(u8 cmd); +void __osPfsGetInitData(u8* pattern, OSContStatus* data); +u8 __osContAddressCrc(u16 addr); +u8 __osContDataCrc(u8 *data); +s32 __osPfsGetStatus(OSMesgQueue *queue, int channel); + +extern u8 __osContLastCmd; +extern OSTimer __osEepromTimer; +extern OSMesg __osEepromTimerMsg; +extern OSMesgQueue __osEepromTimerQ; +extern OSPifRam __osEepPifRam; +extern OSPifRam __osContPifRam; +extern OSPifRam __osPfsPifRam; +extern u8 __osMaxControllers; +extern s32 __osPfsLastChannel; +extern s32 __osEepromRead16K; + +#if LIBULTRA_VERSION >= OS_VER_J +#define CONT_READFORMAT_ADDR(s, d) \ + s->addrh = d >> 3; \ + s->addrl = (__osContAddressCrc(d) | (d << 5)); +#else +#define CONT_READFORMAT_ADDR(s, d) \ + s.address = (d << 5) | __osContAddressCrc(d); +#endif + +#if LIBULTRA_VERSION > OS_VER_H +#define CONT_PIFRAM_SET(addr, cmdram, cmdstatus) \ + for (i = 0; i < ARRAY_COUNT(addr.ramarray); i++) { \ + addr.ramarray[i] = cmdram; \ + } \ + addr.pifstatus = cmdstatus; +#else +// for loop writing out of bounds of ram array +#define CONT_PIFRAM_SET(addr, cmdram, cmdstatus) \ + for (i = 0; i < ARRAY_COUNT(addr.ramarray) + 1; i++) { \ + addr.ramarray[i] = cmdram; \ + } \ + addr.pifstatus = cmdstatus; +#endif + +#if LIBULTRA_VERSION < OS_VER_J +#define CONT_CHECK_BLOCK(ad, bl, er) \ + if (ad > bl) { \ + __osSiRelAccess(); \ + return er; \ + } +#else +#define CONT_CHECK_BLOCK(ad, bl, er) \ + if (ad >= bl) { \ + ret = er; \ + } +#endif + +#define READFORMAT(ptr) ((__OSContRamReadFormat*)(ptr)) +#define REQFORMAT(ptr) ((__OSContRequesFormat*)(ptr)) + +//some version of this almost certainly existed since there's plenty of times where it's used right before a return 0 +#define ERRCK(fn) \ + ret = fn; \ + if (ret != 0) \ + return ret; + +#if LIBULTRA_VERSION >= OS_VER_J +#define SELECT_BANK(pfs, bank) \ + __osPfsSelectBank((pfs), (bank)) + +#define SET_ACTIVEBANK_TO_ZERO \ + if (pfs->activebank != 0) \ + { \ + ERRCK(__osPfsSelectBank(pfs, 0)) \ + } +#else +#define SELECT_BANK(pfs, bank) \ + (pfs->activebank = (bank), \ + __osPfsSelectBank((pfs))) \ + +#define SET_ACTIVEBANK_TO_ZERO \ + if (pfs->activebank != 0) \ + { \ + pfs->activebank = 0; \ + ERRCK(__osPfsSelectBank(pfs)) \ + } +#endif + +#define PFS_CHECK_ID \ + if (__osCheckId(pfs) == PFS_ERR_NEW_PACK) \ + return PFS_ERR_NEW_PACK; + +#define PFS_CHECK_STATUS \ + if ((pfs->status & PFS_INITIALIZED) == 0) \ + return PFS_ERR_INVALID; + +#define PFS_GET_STATUS \ + __osSiGetAccess(); \ + ret = __osPfsGetStatus(queue, channel); \ + __osSiRelAccess(); \ + if (ret != 0) \ + return ret; + +#endif diff --git a/lib/ultra/io/crc.c b/lib/ultra/io/crc.c new file mode 100644 index 00000000..5be2ff22 --- /dev/null +++ b/lib/ultra/io/crc.c @@ -0,0 +1,111 @@ +#include "PR/os_internal.h" + +#if LIBULTRA_VERSION >= OS_VER_J +u8 __osContAddressCrc(u16 addr) { + u32 temp = 0; + u32 i = 0x400; + + do { + temp <<= 1; + + if (addr & i) { + if (temp & 0x20) { + temp ^= 0x14; + } else { + ++temp; + } + } else if (temp & 0x20) { + temp ^= 0x15; + } + + i >>= 1; + } while (i != 0); + + i = 5; + + do { + temp <<= 1; + if (temp & 0x20) { + temp ^= 0x15; + } + } while (--i != 0); + + return temp & 0x1F; +} + +u8 __osContDataCrc(u8* data) { + u32 temp = 0; + u32 i; + u32 j; + + for (i = 0x20; i; --i) { + for (j = 0x80; j; j >>= 1) { + temp <<= 1; + + if ((*data & j) != 0) { + if ((temp & 0x100) != 0) { + temp ^= 0x84; + } else { + ++temp; + } + } else if (temp & 0x100) { + temp ^= 0x85; + } + } + + data++; + } + do { + temp <<= 1; + + if (temp & 0x100) { + temp ^= 0x85; + } + } while (++i < 8U); + + return temp; +} + +#else +u8 __osContAddressCrc(u16 addr) { + u8 temp = 0; + u8 temp2; + int i; + + for (i = 0; i < 16; i++) { + temp2 = (temp & 0x10) ? 0x15 : 0; + + temp <<= 1; + temp |= (u8)((addr & 0x400) ? 1 : 0); + addr <<= 1; + temp ^= temp2; + } + + return temp & 0x1f; +} + +u8 __osContDataCrc(u8 *data) { + u8 temp = 0; + u8 temp2; + int i; + int j; + + for (i = 0; i <= 32; i++) { + for (j = 7; j > -1; j--) { + temp2 = (temp & 0x80) ? 0x85 : 0; + + temp <<= 1; + + if (i == 32) { + temp &= -1; + } else { + temp |= ((*data & (1 << j)) ? 1 : 0); + } + + temp ^= temp2; + } + data++; + } + return temp; +} +#endif diff --git a/lib/ultra/io/devmgr.c b/lib/ultra/io/devmgr.c new file mode 100644 index 00000000..f5284e5b --- /dev/null +++ b/lib/ultra/io/devmgr.c @@ -0,0 +1,196 @@ +#include "PR/os_internal.h" +#include "piint.h" +#include "macros.h" + +#if LIBULTRA_VERSION > OS_VER_D +#include "PR/rcp.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +void __osDevMgrMain(void *args) { + OSIoMesg *mb; + OSMesg em; + OSMesg dummy; + s32 ret; + OSDevMgr *dm = (OSDevMgr *) args; +#if LIBULTRA_VERSION == OS_VER_F + UNUSED u32 sm = 0; +#endif + u32 messageSend = 0; +#ifdef BBPLAYER + s32 check = FALSE; +#endif + + mb = NULL; + ret = 0; + + while (TRUE) { + osRecvMesg(dm->cmdQueue, (OSMesg) &mb, OS_MESG_BLOCK); + + if (mb->piHandle != NULL && + mb->piHandle->type == DEVICE_TYPE_64DD && + (mb->piHandle->transferInfo.cmdType == LEO_CMD_TYPE_0 || + mb->piHandle->transferInfo.cmdType == LEO_CMD_TYPE_1)) { + __OSBlockInfo *blockInfo; + __OSTranxInfo *info; + info = &mb->piHandle->transferInfo; + blockInfo = &info->block[info->blockNum]; + info->sectorNum = -1; + + if (info->transferMode != LEO_SECTOR_MODE) { + blockInfo->dramAddr = (void *) ((u32) blockInfo->dramAddr - blockInfo->sectorSize); + } + + if (info->transferMode == LEO_TRACK_MODE && mb->piHandle->transferInfo.cmdType == LEO_CMD_TYPE_0) { + messageSend = 1; + } else { + messageSend = 0; + } + + osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK); + __osResetGlobalIntMask(OS_IM_PI); + osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, (info->bmCtlShadow | 0x80000000)); + +readblock1: + osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK); +#if LIBULTRA_VERSION >= OS_VER_H + info = &mb->piHandle->transferInfo; + blockInfo = &info->block[info->blockNum]; + + if (blockInfo->errStatus == LEO_ERROR_29) { + u32 stat; + osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_RESET); + osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, info->bmCtlShadow); + osEPiRawReadIo(mb->piHandle, LEO_STATUS, &stat); + + if (stat & LEO_STATUS_MECHANIC_INTERRUPT) { + osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_CLR_MECHANIC_INTR); + } + + blockInfo->errStatus = LEO_ERROR_4; + IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR); + __osSetGlobalIntMask(OS_IM_PI | SR_IBIT4); + } + + osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); + + if (messageSend == 1 && mb->piHandle->transferInfo.block[0].errStatus == LEO_ERROR_GOOD) { + messageSend = 0; + goto readblock1; + } +#else + sm = osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); + + if (messageSend == 1 && mb->piHandle->transferInfo.errStatus == LEO_ERROR_GOOD) { + messageSend = 0; + goto readblock1; + } +#endif + osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK); + + if (mb->piHandle->transferInfo.blockNum == 1) { + osYieldThread(); + } + } else { + switch (mb->hdr.type) { + case OS_MESG_TYPE_DMAREAD: + osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK); +#ifdef BBPLAYER + if (__osBbIsBb == TRUE && ((uintptr_t) mb->dramAddr & 0x7f) >= 0x60) { + check = TRUE; + ret = dm->dma(OS_READ, mb->devAddr, (void *) 0x80600000, mb->size); + break; + } +#endif + ret = dm->dma(OS_READ, mb->devAddr, mb->dramAddr, mb->size); + break; + case OS_MESG_TYPE_DMAWRITE: + osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK); + ret = dm->dma(OS_WRITE, mb->devAddr, mb->dramAddr, mb->size); + break; + case OS_MESG_TYPE_EDMAREAD: + osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK); +#ifdef BBPLAYER + if (__osBbIsBb == TRUE && ((uintptr_t) mb->dramAddr & 0x7f) >= 0x60) { + check = TRUE; + ret = dm->edma(mb->piHandle, OS_READ, mb->devAddr, (void *) 0x80600000, mb->size); + break; + } +#endif + ret = dm->edma(mb->piHandle, OS_READ, mb->devAddr, mb->dramAddr, mb->size); + break; + case OS_MESG_TYPE_EDMAWRITE: + osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK); + ret = dm->edma(mb->piHandle, OS_WRITE, mb->devAddr, mb->dramAddr, + mb->size); + break; + case OS_MESG_TYPE_LOOPBACK: + osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); + ret = -1; + break; + break; + default: + ret = -1; + break; + } + + if (ret == 0) { + osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK); +#ifdef BBPLAYER + if (__osBbIsBb == TRUE && check) { + osInvalDCache((void *) 0x80600000, (mb->size + DCACHE_LINEMASK) & ~DCACHE_LINEMASK); + bcopy((void *) 0x80600000, mb->dramAddr, mb->size); + check = FALSE; + osWritebackDCache(mb->dramAddr, mb->size); + } +#endif +#if LIBULTRA_VERSION == OS_VER_F + sm = +#endif + osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); + osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK); + } + } + } +} +#else +void __osDevMgrMain(void *args) { + OSIoMesg *mb; + OSMesg em; + OSMesg messageSend; + s32 ret; + OSDevMgr *dm = (OSDevMgr *) args; + + mb = NULL; + ret = 0; + + while (TRUE) { + osRecvMesg(dm->cmdQueue, (OSMesg) &mb, OS_MESG_BLOCK); + + switch (mb->hdr.type) { + case OS_MESG_TYPE_DMAREAD: + osRecvMesg(dm->acsQueue, &messageSend, OS_MESG_BLOCK); + ret = dm->dma(OS_READ, mb->devAddr, mb->dramAddr, mb->size); + break; + case OS_MESG_TYPE_DMAWRITE: + osRecvMesg(dm->acsQueue, &messageSend, OS_MESG_BLOCK); + ret = dm->dma(OS_WRITE, mb->devAddr, mb->dramAddr, mb->size); + break; + case OS_MESG_TYPE_LOOPBACK: + osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); + ret = -1; + break; + default: + ret = -1; + break; + } + + if (ret == 0) { + osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK); + osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); + osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK); + } + } +} +#endif diff --git a/lib/src/osDriveRomInit.c b/lib/ultra/io/driverominit.c similarity index 53% rename from lib/src/osDriveRomInit.c rename to lib/ultra/io/driverominit.c index 9bfc1de4..4969988f 100644 --- a/lib/src/osDriveRomInit.c +++ b/lib/ultra/io/driverominit.c @@ -1,27 +1,42 @@ -#include "libultra_internal.h" -#include "PR/os_pi.h" +#include "PR/os_internal.h" +#include "PR/os.h" #include "PR/rcp.h" -#include "bstring.h" -#include +#include "macros.h" -extern OSPiHandle *__osPiTable; +// The existence of this file is due to updated audio library in the game +#ifdef LIBULTRA_EXCLUSIVE +ALIGNED8 OSPiHandle DriveRomHandle; +#else extern OSPiHandle DriveRomHandle; +#endif -OSPiHandle *osDriveRomInit(void) { // Why is this compiled with -g??? - UNUSED s32 sp1c = 0; +OSPiHandle *osDriveRomInit(void) { +#if LIBULTRA_VERSION < OS_VER_I || !defined(LIBULTRA_EXCLUSIVE) + UNUSED s32 dummy = 0; +#endif u32 saveMask; +#if LIBULTRA_VERSION >= OS_VER_J && defined(LIBULTRA_EXCLUSIVE) + if (DriveRomHandle.baseAddress == PHYS_TO_K1(PI_DOM1_ADDR1)) { + return &DriveRomHandle; + } +#endif + DriveRomHandle.type = DEVICE_TYPE_BULK; DriveRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR1); DriveRomHandle.latency = 64; DriveRomHandle.pulse = 7; DriveRomHandle.pageSize = 7; DriveRomHandle.relDuration = 2; - +#if LIBULTRA_VERSION >= OS_VER_J && defined(LIBULTRA_EXCLUSIVE) + DriveRomHandle.domain = PI_DOMAIN1; + DriveRomHandle.speed = 0; +#else IO_WRITE(PI_BSD_DOM1_LAT_REG, DriveRomHandle.latency); IO_WRITE(PI_BSD_DOM1_PWD_REG, DriveRomHandle.pulse); IO_WRITE(PI_BSD_DOM1_PGS_REG, DriveRomHandle.pageSize); IO_WRITE(PI_BSD_DOM1_RLS_REG, DriveRomHandle.relDuration); +#endif bzero(&DriveRomHandle.transferInfo, sizeof(__OSTranxInfo)); diff --git a/lib/src/epidma.c b/lib/ultra/io/epidma.c similarity index 88% rename from lib/src/epidma.c rename to lib/ultra/io/epidma.c index 0206fcc7..52aff902 100644 --- a/lib/src/epidma.c +++ b/lib/ultra/io/epidma.c @@ -1,26 +1,27 @@ -#if defined(VERSION_SH) || defined(VERSION_CN) - -#include "PR/os_internal.h" #include "piint.h" +#if LIBULTRA_VERSION > OS_VER_D s32 osEPiStartDma(OSPiHandle *pihandle, OSIoMesg *mb, s32 direction) { register s32 ret; if (!__osPiDevMgr.active) { return -1; } + mb->piHandle = pihandle; + if (direction == OS_READ) { mb->hdr.type = OS_MESG_TYPE_EDMAREAD; } else { mb->hdr.type = OS_MESG_TYPE_EDMAWRITE; } + if (mb->hdr.pri == OS_MESG_PRI_HIGH) { ret = osJamMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); } else { ret = osSendMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); } + return ret; } - #endif diff --git a/lib/ultra/io/epirawdma.c b/lib/ultra/io/epirawdma.c new file mode 100644 index 00000000..af3b649a --- /dev/null +++ b/lib/ultra/io/epirawdma.c @@ -0,0 +1,120 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "PR/R4300.h" +#include "piint.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +s32 osEPiRawStartDma(OSPiHandle *pihandle, s32 direction, u32 devAddr, void *dramAddr, u32 size) { +#ifdef BBPLAYER + u64 dummyBuf[2]; + u32 stat; + u32 domain; + u32 buffer; + u32 pgsize; + u16 *adr; + u32 i; +#elif LIBULTRA_VERSION >= OS_VER_H + u32 stat; + u32 domain; +#else + register u32 stat; +#endif + +#if LIBULTRA_VERSION >= OS_VER_H + EPI_SYNC(pihandle, stat, domain); +#else + WAIT_ON_IO_BUSY(stat); +#endif + +#ifdef BBPLAYER + if (direction == OS_READ) { + pgsize = 1; + + for (i = 1; i <= (u32) (pihandle->pageSize + 2); i++) { + pgsize *= 2; + } + + if ((devAddr & (pgsize - 1)) == pgsize - 2) { + osEPiRawReadIo(pihandle, devAddr - 2, &buffer); + + adr = (u16 *) PHYS_TO_K1(dramAddr); + *(adr++) = (u16) buffer; + + devAddr += 2; + dramAddr = adr; + size -= 2; + + if (size >= 4) { + osEPiRawReadIo(pihandle, devAddr, &buffer); + + adr = (u16 *) dramAddr; + *(adr++) = buffer >> 16; + *(adr++) = (u16) buffer; + + devAddr += 4; + dramAddr = adr; + size -= 4; + + if (size != 0) { + osEPiRawReadIo(pihandle, devAddr, &buffer); + + adr = (u16 *) PHYS_TO_K1(dramAddr); + *(adr++) = buffer >> 16; + + devAddr += 2; + dramAddr = adr; + size -= 2; + } + } + } + + if ((((devAddr + size) & (pgsize - 1)) == 2) | (size == 2)) { + if ((devAddr + size) & 2) { + osEPiRawReadIo(pihandle, devAddr + size - 2, &buffer); + adr = (u16 *) PHYS_TO_K1(dramAddr) + (size - 2) / 2; + *adr = buffer >> 16; + } else { + osEPiRawReadIo(pihandle, devAddr + size - 4, &buffer); + adr = (u16 *) PHYS_TO_K1(dramAddr) + (size - 2) / 2; + *adr = (u16) buffer; + } + size -= 2; + } + + if (size == 0) { + size = 8; + dramAddr = dummyBuf; + devAddr = 0; + } + } +#endif + + IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr)); + IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS(pihandle->baseAddress | devAddr)); + +#ifdef BBPLAYER + if ((u32) direction >= 2U) { + return -1; + } + + if ((pihandle->baseAddress | devAddr) <= 0x400) { + IO_WRITE(direction == OS_READ ? PI_5C_REG : PI_58_REG, size - 1); + } else { + IO_WRITE(direction == OS_READ ? PI_WR_LEN_REG : PI_RD_LEN_REG, size - 1); + } +#else + switch (direction) { + case OS_READ: + IO_WRITE(PI_WR_LEN_REG, size - 1); + break; + case OS_WRITE: + IO_WRITE(PI_RD_LEN_REG, size - 1); + break; + default: + return -1; + } +#endif + return 0; +} diff --git a/lib/src/osEPiRawReadIo.c b/lib/ultra/io/epirawread.c similarity index 71% rename from lib/src/osEPiRawReadIo.c rename to lib/ultra/io/epirawread.c index 1f1ab384..703e0239 100644 --- a/lib/src/osEPiRawReadIo.c +++ b/lib/ultra/io/epirawread.c @@ -1,19 +1,16 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" #include "piint.h" s32 osEPiRawReadIo(OSPiHandle *pihandle, u32 devAddr, u32 *data) { register s32 stat; -#ifdef VERSION_CN - u32 domain; +#if LIBULTRA_VERSION > OS_VER_H + register u32 domain; #endif -#ifdef VERSION_CN +#if LIBULTRA_VERSION > OS_VER_H EPI_SYNC(pihandle, stat, domain); #else WAIT_ON_IO_BUSY(stat); #endif - *data = IO_READ(pihandle->baseAddress | devAddr); return 0; diff --git a/lib/src/osEPiRawWriteIo.c b/lib/ultra/io/epirawwrite.c similarity index 71% rename from lib/src/osEPiRawWriteIo.c rename to lib/ultra/io/epirawwrite.c index 1f67b70e..256d92a2 100644 --- a/lib/src/osEPiRawWriteIo.c +++ b/lib/ultra/io/epirawwrite.c @@ -1,19 +1,16 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" #include "piint.h" s32 osEPiRawWriteIo(OSPiHandle *pihandle, u32 devAddr, u32 data) { register u32 stat; -#ifdef VERSION_CN - u32 domain; +#if LIBULTRA_VERSION > OS_VER_H + register u32 domain; #endif -#ifdef VERSION_CN +#if LIBULTRA_VERSION > OS_VER_H EPI_SYNC(pihandle, stat, domain); #else WAIT_ON_IO_BUSY(stat); #endif - IO_WRITE(pihandle->baseAddress | devAddr, data); return 0; diff --git a/lib/ultra/io/leodiskinit.c b/lib/ultra/io/leodiskinit.c new file mode 100644 index 00000000..9c652367 --- /dev/null +++ b/lib/ultra/io/leodiskinit.c @@ -0,0 +1,39 @@ +#include "PR/os_internal.h" +#include "PR/os.h" +#include "PR/rcp.h" +#include "macros.h" + +// This file was removed in 2.0J +ALIGNED8 OSPiHandle LeoDiskHandle; +OSPiHandle *__osDiskHandle; + +OSPiHandle *osLeoDiskInit(void) { + u32 saveMask; + + LeoDiskHandle.type = DEVICE_TYPE_64DD; + LeoDiskHandle.baseAddress = PHYS_TO_K1(PI_DOM2_ADDR1); + LeoDiskHandle.latency = 3; + LeoDiskHandle.pulse = 6; + LeoDiskHandle.pageSize = 6; + LeoDiskHandle.relDuration = 2; +#if LIBULTRA_VERSION >= OS_VER_H + LeoDiskHandle.domain = PI_DOMAIN2; +#endif + + IO_WRITE(PI_BSD_DOM2_LAT_REG, LeoDiskHandle.latency); + IO_WRITE(PI_BSD_DOM2_PWD_REG, LeoDiskHandle.pulse); + IO_WRITE(PI_BSD_DOM2_PGS_REG, LeoDiskHandle.pageSize); + IO_WRITE(PI_BSD_DOM2_RLS_REG, LeoDiskHandle.relDuration); +#if LIBULTRA_VERSION >= OS_VER_I + LeoDiskHandle.speed = 0; +#endif + + bzero(&LeoDiskHandle.transferInfo, sizeof(__OSTranxInfo)); + saveMask = __osDisableInt(); + LeoDiskHandle.next = __osPiTable; + __osPiTable = &LeoDiskHandle; + __osDiskHandle = &LeoDiskHandle; + __osRestoreInt(saveMask); + + return &LeoDiskHandle; +} diff --git a/lib/src/leointerrupt.c b/lib/ultra/io/leointerrupt.c similarity index 80% rename from lib/src/leointerrupt.c rename to lib/ultra/io/leointerrupt.c index 32ffb2b7..0a27837b 100644 --- a/lib/src/leointerrupt.c +++ b/lib/ultra/io/leointerrupt.c @@ -1,81 +1,81 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/rcp.h" -#include "bstring.h" -#include "new_func.h" -#include "macros.h" +#include "../os/osint.h" #include "piint.h" -#include "osint.h" - -u8 leoDiskStack[OS_PIM_STACKSIZE]; // technically should have a OS_LEO_STACKSIZE or something.. +#include "macros.h" +extern u32 __osLeoPresent; static void __osLeoResume(void); static void __osLeoAbnormalResume(void); +ALIGNED16 u8 leoDiskStack[OS_LEO_STACKSIZE]; + s32 __osLeoInterrupt(void) { +#if LIBULTRA_VERSION == OS_VER_F u32 stat; -#ifdef VERSION_EU - u32 pi_stat; -#else // VERSION_SH - volatile u32 pi_stat; + u32 pistat; +#else + u32 stat = 0; + volatile u32 pistat; #endif - u32 bm_stat; + u32 bmstat; __OSTranxInfo *info; __OSBlockInfo *blockInfo; -#ifdef VERSION_EU - if (!osDDActive) { +#if LIBULTRA_VERSION == OS_VER_F + if (!__osLeoPresent) { return 0; } -#else // VERSION_SH - stat = 0; #endif info = &__osDiskHandle->transferInfo; blockInfo = &info->block[info->blockNum]; - pi_stat = IO_READ(PI_STATUS_REG); - if (pi_stat & PI_STATUS_DMA_BUSY) { -#ifdef VERSION_EU + + pistat = IO_READ(PI_STATUS_REG); + if (pistat & PI_STATUS_DMA_BUSY) { +#if LIBULTRA_VERSION == OS_VER_F IO_WRITE(PI_STATUS_REG, PI_STATUS_RESET | PI_STATUS_CLR_INTR); - WAIT_ON_LEO_IO_BUSY(pi_stat); + WAIT_ON_LEO_IO_BUSY(pistat); stat = IO_READ(LEO_STATUS); if (stat & LEO_STATUS_MECHANIC_INTERRUPT) { - WAIT_ON_LEO_IO_BUSY(pi_stat); + WAIT_ON_LEO_IO_BUSY(pistat); IO_WRITE(LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_CLR_MECHANIC_INTR); } info->errStatus = LEO_ERROR_75; __osLeoAbnormalResume(); -#else // VERSION_SH +#else __OSGlobalIntMask = __OSGlobalIntMask & ~SR_IBIT4; //cartridge interrupt blockInfo->errStatus = LEO_ERROR_29; __osLeoResume(); #endif return 1; } - WAIT_ON_LEO_IO_BUSY(pi_stat); + WAIT_ON_LEO_IO_BUSY(pistat); + stat = IO_READ(LEO_STATUS); if (stat & LEO_STATUS_MECHANIC_INTERRUPT) { - WAIT_ON_LEO_IO_BUSY(pi_stat); + WAIT_ON_LEO_IO_BUSY(pistat); IO_WRITE(LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_CLR_MECHANIC_INTR); -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_GOOD; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_GOOD; #endif return 0; } -#ifdef VERSION_SH +#if LIBULTRA_VERSION > OS_VER_F if (info->cmdType == LEO_CMD_TYPE_2) { return 1; } #endif if (stat & LEO_STATUS_BUFFER_MANAGER_ERROR) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_3; __osLeoAbnormalResume(); -#else //VERSION_SH - WAIT_ON_LEO_IO_BUSY(pi_stat); +#else + WAIT_ON_LEO_IO_BUSY(pistat); stat = IO_READ(LEO_STATUS); blockInfo->errStatus = LEO_ERROR_22; __osLeoResume(); @@ -88,9 +88,9 @@ s32 __osLeoInterrupt(void) { if (info->cmdType == LEO_CMD_TYPE_1) { if ((stat & LEO_STATUS_DATA_REQUEST) == 0) { if (info->sectorNum + 1 != info->transferMode * 85) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_6; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_24; #endif __osLeoAbnormalResume(); @@ -98,34 +98,36 @@ s32 __osLeoInterrupt(void) { } IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR); __OSGlobalIntMask |= OS_IM_PI; -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_GOOD; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_GOOD; #endif __osLeoResume(); return 1; } + blockInfo->dramAddr = (void *) ((u32)blockInfo->dramAddr + blockInfo->sectorSize); info->sectorNum++; osEPiRawStartDma(__osDiskHandle, OS_WRITE, LEO_SECTOR_BUFF, blockInfo->dramAddr, blockInfo->sectorSize); return 1; } + if (info->cmdType == LEO_CMD_TYPE_0) { if (info->transferMode == LEO_SECTOR_MODE) { if ((s32)blockInfo->C1ErrNum + 17 < info->sectorNum) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_GOOD; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_GOOD; #endif __osLeoAbnormalResume(); return 1; } if ((stat & LEO_STATUS_DATA_REQUEST) == 0) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_17; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_23; #endif __osLeoAbnormalResume(); @@ -134,13 +136,13 @@ s32 __osLeoInterrupt(void) { } else { blockInfo->dramAddr = (void *)((u32)blockInfo->dramAddr + blockInfo->sectorSize); } - bm_stat = IO_READ(LEO_BM_STATUS); - if ((bm_stat & LEO_BM_STATUS_C1SINGLE && bm_stat & LEO_BM_STATUS_C1DOUBLE) || bm_stat & LEO_BM_STATUS_MICRO) { + bmstat = IO_READ(LEO_BM_STATUS); + if ((bmstat & LEO_BM_STATUS_C1SINGLE && bmstat & LEO_BM_STATUS_C1DOUBLE) || bmstat & LEO_BM_STATUS_MICRO) { if (blockInfo->C1ErrNum > 3) { if (info->transferMode != LEO_SECTOR_MODE || info->sectorNum > 0x52) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_17; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_23; #endif __osLeoAbnormalResume(); @@ -155,9 +157,9 @@ s32 __osLeoInterrupt(void) { if (stat & LEO_STATUS_C2_TRANSFER) { if (info->sectorNum != 87) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_6; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_24; #endif __osLeoAbnormalResume(); @@ -166,19 +168,19 @@ s32 __osLeoInterrupt(void) { info->blockNum = 1; info->sectorNum = -1; info->block[1].dramAddr = (void *)((u32)info->block[1].dramAddr - info->block[1].sectorSize); -#ifdef VERSION_SH +#if LIBULTRA_VERSION > OS_VER_F blockInfo->errStatus = LEO_ERROR_22; #endif } else { IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR); __OSGlobalIntMask |= OS_IM_PI; -#ifdef VERSION_SH +#if LIBULTRA_VERSION > OS_VER_F info->cmdType = LEO_CMD_TYPE_2; blockInfo->errStatus = LEO_ERROR_GOOD; #endif } osEPiRawStartDma(__osDiskHandle, OS_READ, LEO_C2_BUFF, blockInfo->C2Addr, blockInfo->sectorSize * 4); -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_GOOD; #endif return 1; @@ -187,18 +189,18 @@ s32 __osLeoInterrupt(void) { __OSBlockInfo *bptr = &info->block[0]; if (bptr->C1ErrNum == 0) { if (((u32 *)bptr->C2Addr)[0] | ((u32 *)bptr->C2Addr)[1] | ((u32 *)bptr->C2Addr)[2] | ((u32 *)bptr->C2Addr)[3]) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_6; -#else // VERSION_SH +#else bptr->errStatus = LEO_ERROR_24; #endif __osLeoAbnormalResume(); return 1; } } -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_GOOD; -#else // VERSION_SH +#else bptr->errStatus = LEO_ERROR_GOOD; #endif __osLeoResume(); @@ -206,26 +208,26 @@ s32 __osLeoInterrupt(void) { info->sectorNum++; if (stat & LEO_STATUS_DATA_REQUEST) { if (info->sectorNum > 0x54) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_6; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_24; #endif __osLeoAbnormalResume(); return 1; } osEPiRawStartDma(__osDiskHandle, 0, LEO_SECTOR_BUFF, blockInfo->dramAddr, blockInfo->sectorSize); -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_GOOD; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_GOOD; #endif return 1; } if (info->sectorNum <= 0x54) { -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_6; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_24; #endif __osLeoAbnormalResume(); @@ -233,9 +235,10 @@ s32 __osLeoInterrupt(void) { } return 1; } -#ifdef VERSION_EU + +#if LIBULTRA_VERSION == OS_VER_F info->errStatus = LEO_ERROR_75; -#else // VERSION_SH +#else blockInfo->errStatus = LEO_ERROR_4; #endif @@ -244,30 +247,32 @@ s32 __osLeoInterrupt(void) { } static void __osLeoAbnormalResume(void) { - __OSTranxInfo *info; - u32 pi_stat; - info = &__osDiskHandle->transferInfo; - WAIT_ON_LEO_IO_BUSY(pi_stat); + __OSTranxInfo *info = &__osDiskHandle->transferInfo; + u32 pistat; + + WAIT_ON_LEO_IO_BUSY(pistat); IO_WRITE(LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_RESET); - WAIT_ON_LEO_IO_BUSY(pi_stat); + WAIT_ON_LEO_IO_BUSY(pistat); IO_WRITE(LEO_BM_CTL, info->bmCtlShadow); __osLeoResume(); IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR); + __OSGlobalIntMask |= OS_IM_PI; } static void __osLeoResume(void) { - __OSEventState *es; - OSMesgQueue *mq; + __OSEventState *es = &__osEventStateTab[OS_EVENT_PI]; + OSMesgQueue *mq = es->messageQueue; s32 last; - es = &__osEventStateTab[OS_EVENT_PI]; - mq = es->messageQueue; + if (mq == NULL || MQ_IS_FULL(mq)) { return; } + last = (mq->first + mq->validCount) % mq->msgCount; mq->msg[last] = es->message; mq->validCount++; + if (mq->mtqueue->next != NULL) { __osEnqueueThread(&__osRunQueue, __osPopThread(&mq->mtqueue)); } diff --git a/lib/ultra/io/motor.c b/lib/ultra/io/motor.c new file mode 100644 index 00000000..5437361f --- /dev/null +++ b/lib/ultra/io/motor.c @@ -0,0 +1,292 @@ +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" + +#ifdef BBPLAYER + +s32 __osMotorAccess(UNUSED OSPfs *pfs, UNUSED s32 action) { + return PFS_ERR_INVALID; +} + +s32 osMotorInit(UNUSED OSMesgQueue *mq, UNUSED OSPfs *pfs, UNUSED int channel) { + return PFS_ERR_DEVICE; +} + +#else + +#if LIBULTRA_VERSION >= OS_VER_J +static OSPifRam __MotorDataBuf[MAXCONTROLLERS]; +#else +void __osMakeMotorData(int channel, u16 address, u8 *buffer, OSPifRam *mdata); +u32 __osMotorinitialized[MAXCONTROLLERS] = { 0, 0, 0, 0 }; +OSPifRam _MotorStopData[MAXCONTROLLERS]; +OSPifRam _MotorStartData[MAXCONTROLLERS]; +ALIGNED8 u8 _motorstopbuf[32]; +ALIGNED8 u8 _motorstartbuf[32]; +#endif + +#if LIBULTRA_VERSION >= OS_VER_J +s32 __osMotorAccess(OSPfs* pfs, s32 flag) { + int i; + s32 ret; + u8* ptr = (u8*)&__MotorDataBuf[pfs->channel]; + + if (!(pfs->status & PFS_MOTOR_INITIALIZED)) { + return 5; + } + + __osSiGetAccess(); + __MotorDataBuf[pfs->channel].pifstatus = CONT_CMD_EXE; + ptr += pfs->channel; + + for (i = 0; i < BLOCKSIZE; i++) { + READFORMAT(ptr)->data[i] = flag; + } + + __osContLastCmd = CONT_CMD_END; + __osSiRawStartDma(OS_WRITE, &__MotorDataBuf[pfs->channel]); + osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__MotorDataBuf[pfs->channel]); + osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); + + ret = READFORMAT(ptr)->rxsize & CHNL_ERR_MASK; + if (!ret) { + if (!flag) { + if (READFORMAT(ptr)->datacrc != 0) { + ret = PFS_ERR_CONTRFAIL; + } + } else { + if (READFORMAT(ptr)->datacrc != 0xEB) { + ret = PFS_ERR_CONTRFAIL; + } + } + } + + __osSiRelAccess(); + + return ret; +} + +#else + +s32 osMotorStop(OSPfs *pfs) { + int i; + s32 ret; + u8 *ptr; + __OSContRamReadFormat ramreadformat; + ptr = (u8 *) &__osPfsPifRam; + + if (!__osMotorinitialized[pfs->channel]) { + return PFS_ERR_INVALID; + } + + __osSiGetAccess(); + + __osContLastCmd = CONT_CMD_WRITE_PAK; + __osSiRawStartDma(OS_WRITE, &_MotorStopData[pfs->channel]); + osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); + ptr = (u8 *) &__osPfsPifRam; + + if (pfs->channel != 0) { + for (i = 0; i < pfs->channel; i++) { + ptr++; + } + } + + ramreadformat = *READFORMAT(ptr); + ret = CHNL_ERR(ramreadformat); + if (ret == 0 && ramreadformat.datacrc != __osContDataCrc((u8 *) &_motorstopbuf)) { + ret = PFS_ERR_CONTRFAIL; + } + + __osSiRelAccess(); + return ret; +} + +s32 osMotorStart(OSPfs *pfs) { + int i; + s32 ret; + u8 *ptr; + __OSContRamReadFormat ramreadformat; + + ptr = (u8 *) &__osPfsPifRam; + + if (!__osMotorinitialized[pfs->channel]) { + return PFS_ERR_INVALID; + } + + __osSiGetAccess(); + + __osContLastCmd = CONT_CMD_WRITE_PAK; + __osSiRawStartDma(OS_WRITE, &_MotorStartData[pfs->channel]); + osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); + ptr = (u8 *) &__osPfsPifRam; + + if (pfs->channel != 0) { + for (i = 0; i < pfs->channel; i++) { + ptr++; + } + } + + ramreadformat = *READFORMAT(ptr); + ret = CHNL_ERR(ramreadformat); + if (ret == 0 && ramreadformat.datacrc != __osContDataCrc((u8 *) &_motorstartbuf)) { + ret = PFS_ERR_CONTRFAIL; + } + __osSiRelAccess(); + return ret; +} +#endif + +#if LIBULTRA_VERSION >= OS_VER_J +void __osMakeMotorData(int channel, OSPifRam* mdata) +#else // _MakeMotorData +void __osMakeMotorData(int channel, u16 address, u8 *buffer, OSPifRam *mdata) +#endif +{ + u8 *ptr = (u8 *) mdata->ramarray; + __OSContRamReadFormat ramreadformat; + int i; + +#if LIBULTRA_VERSION < OS_VER_J + for (i = 0; i < ARRAY_COUNT(mdata->ramarray); i++) { + mdata->ramarray[i] = 0; + } + mdata->pifstatus = CONT_CMD_EXE; +#endif + + ramreadformat.dummy = CONT_CMD_NOP; + ramreadformat.txsize = CONT_CMD_WRITE_PAK_TX; + ramreadformat.rxsize = CONT_CMD_WRITE_PAK_RX; + ramreadformat.cmd = CONT_CMD_WRITE_PAK; + +#if LIBULTRA_VERSION >= OS_VER_J + ramreadformat.addrh = CONT_BLOCK_RUMBLE >> 3; + ramreadformat.addrl = (u8)(__osContAddressCrc(CONT_BLOCK_RUMBLE) | (CONT_BLOCK_RUMBLE << 5)); +#else + ramreadformat.address = (address << 0x5) | __osContAddressCrc(address); + ramreadformat.datacrc = CONT_CMD_NOP; + + for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) { + ramreadformat.data[i] = *buffer++; + } +#endif + + if (channel != 0) { + for (i = 0; i < channel; i++) { + *ptr++ = 0; + } + } + + *READFORMAT(ptr) = ramreadformat; + ptr += sizeof(__OSContRamReadFormat); + ptr[0] = CONT_CMD_END; +} + +s32 osMotorInit(OSMesgQueue *mq, OSPfs *pfs, int channel) { +#if LIBULTRA_VERSION < OS_VER_J + int i; +#endif + s32 ret; + u8 temp[32]; + + pfs->queue = mq; + pfs->channel = channel; +#if LIBULTRA_VERSION >= OS_VER_J + pfs->activebank = 0xFF; + pfs->status = 0; + + ret = SELECT_BANK(pfs, 0xFE); + + if (ret == PFS_ERR_NEW_PACK) { + ret = SELECT_BANK(pfs, 0x80); + } +#else + pfs->status = 0; + pfs->activebank = 0x80; + + for (i = 0; i < ARRAY_COUNT(temp); i++) { + temp[i] = 254; + } + + ret = __osContRamWrite(mq, channel, CONT_BLOCK_DETECT, temp, FALSE); + if (ret == PFS_ERR_NEW_PACK) { + ret = __osContRamWrite(mq, channel, CONT_BLOCK_DETECT, temp, FALSE); + } +#endif + + if (ret != 0) { + return ret; + } + + ret = __osContRamRead(mq, channel, CONT_BLOCK_DETECT, temp); + if (ret == PFS_ERR_NEW_PACK) { + ret = PFS_ERR_CONTRFAIL; + } + + if (ret != 0) { + return ret; + } + + if (temp[31] == 254) { + return PFS_ERR_DEVICE; + } + +#if LIBULTRA_VERSION >= OS_VER_J + ret = __osPfsSelectBank(pfs, 0x80); + if (ret == PFS_ERR_NEW_PACK) { + ret = PFS_ERR_CONTRFAIL; + } +#else + for (i = 0; i < ARRAY_COUNT(temp); i++) { + temp[i] = 128; + } + + ret = __osContRamWrite(mq, channel, CONT_BLOCK_DETECT, temp, FALSE); + if (ret == PFS_ERR_NEW_PACK) { + ret = __osContRamWrite(mq, channel, CONT_BLOCK_DETECT, temp, FALSE); + } + + if (ret != 0) { + return ret; + } +#endif + ret = __osContRamRead(mq, channel, CONT_BLOCK_DETECT, temp); + if (ret == PFS_ERR_NEW_PACK) { + ret = PFS_ERR_CONTRFAIL; + } + + if (ret != 0) { + return ret; + } + + if (temp[31] != 0x80) { + return PFS_ERR_DEVICE; + } + +#if LIBULTRA_VERSION >= OS_VER_J + if (!(pfs->status & PFS_MOTOR_INITIALIZED)) { + __osMakeMotorData(channel, &__MotorDataBuf[channel]); + } + + pfs->status = PFS_MOTOR_INITIALIZED; +#else + if (!__osMotorinitialized[channel]) { + for (i = 0; i < ARRAY_COUNT(_motorstartbuf); i++) { + _motorstartbuf[i] = 1; + _motorstopbuf[i] = 0; + } + __osMakeMotorData(channel, CONT_BLOCK_RUMBLE, _motorstartbuf, &_MotorStartData[channel]); + __osMakeMotorData(channel, CONT_BLOCK_RUMBLE, _motorstopbuf, &_MotorStopData[channel]); + __osMotorinitialized[channel] = TRUE; + } +#endif + + return 0; +} + +#endif diff --git a/lib/ultra/io/pfsgetstatus.c b/lib/ultra/io/pfsgetstatus.c new file mode 100644 index 00000000..3840c3cc --- /dev/null +++ b/lib/ultra/io/pfsgetstatus.c @@ -0,0 +1,132 @@ +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#if LIBULTRA_VERSION > OS_VER_H + +#if LIBULTRA_VERSION >= OS_VER_J +void __osPfsRequestOneChannel(int channel, u8 cmd); +#else +void __osPfsRequestOneChannel(int channel); +#endif + +void __osPfsGetOneChannelData(int channel, OSContStatus* data); +#endif + +#ifdef BBPLAYER +s32 __osPfsGetStatus(UNUSED OSMesgQueue *queue, s32 channel) { + if (__osBbPakAddress[channel] != 0) { + return 0; + } + return PFS_ERR_NOPACK; +} +#else +s32 __osPfsGetStatus(OSMesgQueue *queue, s32 channel) { + s32 ret = 0; + OSMesg dummy; +#if LIBULTRA_VERSION > OS_VER_H + OSContStatus data; +#define DATA(c) data +#else + u8 pattern; + OSContStatus data[MAXCONTROLLERS]; +#define DATA(c) data[c] +#endif + +#if LIBULTRA_VERSION >= OS_VER_J + __osPfsRequestOneChannel(channel, CONT_CMD_REQUEST_STATUS); +#elif LIBULTRA_VERSION > OS_VER_H + __osPfsRequestOneChannel(channel); +#else + __osPfsRequestData(CONT_CMD_REQUEST_STATUS); +#endif + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(queue, &dummy, OS_MESG_BLOCK); + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(queue, &dummy, OS_MESG_BLOCK); +#if LIBULTRA_VERSION > OS_VER_H + __osPfsGetOneChannelData(channel, &data); +#else + __osPfsGetInitData(&pattern, data); +#endif + + if (DATA(channel).status & CONT_CARD_ON && DATA(channel).status & CONT_CARD_PULL) { + return PFS_ERR_NEW_PACK; + } else if (DATA(channel).errnum || !(DATA(channel).status & CONT_CARD_ON)) { + return PFS_ERR_NOPACK; + } else if (DATA(channel).status & CONT_ADDR_CRC_ER) { + return PFS_ERR_CONTRFAIL; + } + + return ret; +} +#endif + +#if LIBULTRA_VERSION > OS_VER_H + +#if LIBULTRA_VERSION >= OS_VER_J +void __osPfsRequestOneChannel(int channel, u8 cmd) +#else +void __osPfsRequestOneChannel(int channel) +#endif +{ + u8* ptr; + __OSContRequesFormat requestformat; + int i; + +#if LIBULTRA_VERSION >= OS_VER_J + __osContLastCmd = CONT_CMD_END; +#else + __osContLastCmd = CONT_CMD_REQUEST_STATUS; +#endif +#if LIBULTRA_VERSION > OS_VER_H + __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; +#else + __osPfsPifRam.pifstatus = CONT_CMD_EXE; +#endif + + ptr = (u8*)&__osPfsPifRam; + + requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX; + requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; +#if LIBULTRA_VERSION >= OS_VER_J + requestformat.cmd = cmd; +#else + requestformat.cmd = CONT_CMD_REQUEST_STATUS; +#endif + requestformat.typeh = CONT_CMD_NOP; + requestformat.typel = CONT_CMD_NOP; + requestformat.status = CONT_CMD_NOP; + + for (i = 0; i < channel; i++) { + *ptr++ = CONT_CMD_REQUEST_STATUS; + } + + *REQFORMAT(ptr) = requestformat; + ptr += sizeof(requestformat); + *ptr = CONT_CMD_END; +} + +void __osPfsGetOneChannelData(int channel, OSContStatus* data) { + u8* ptr = (u8*)&__osPfsPifRam; + __OSContRequesFormat requestformat; + int i; + + for (i = 0; i < channel; i++) { + ptr++; + } + + requestformat = *REQFORMAT(ptr); + data->errnum = CHNL_ERR(requestformat); + + if (data->errnum != 0) { + return; + } + + data->type = (requestformat.typel << 8) | (requestformat.typeh); + data->status = requestformat.status; +} +#endif diff --git a/lib/ultra/io/pfsisplug.c b/lib/ultra/io/pfsisplug.c new file mode 100644 index 00000000..0d9743ad --- /dev/null +++ b/lib/ultra/io/pfsisplug.c @@ -0,0 +1,107 @@ +#include "PR/os_pi.h" +#include "PR/os_internal.h" +#include "controller.h" +#include "macros.h" + +ALIGNED16 OSPifRam __osPfsPifRam; + +s32 osPfsIsPlug(OSMesgQueue *mq, u8 *pattern) { + s32 ret = 0; + OSMesg dummy; + u8 bitpattern; + OSContStatus contData[MAXCONTROLLERS]; + int channel; + u8 bits = 0; + int crcErrorCount = 3; + + __osSiGetAccess(); + + do { + __osPfsRequestData(CONT_CMD_REQUEST_STATUS); + + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); + + __osPfsGetInitData(&bitpattern, contData); + for (channel = 0; channel < __osMaxControllers; channel++) { + if ((contData[channel].status & CONT_ADDR_CRC_ER) == 0) { + crcErrorCount--; + break; + } + } + + if (__osMaxControllers == channel) { + crcErrorCount = 0; + } + } while (crcErrorCount > 0); + + for (channel = 0; channel < __osMaxControllers; channel++) { + if ((contData[channel].errnum == 0) && ((contData[channel].status & CONT_CARD_ON) != 0)) { + bits |= 1 << channel; + } + } + __osSiRelAccess(); + *pattern = bits; + return ret; +} + +void __osPfsRequestData(u8 cmd) { + u8 *ptr; + __OSContRequesFormat requestformat; + int i; + +#if LIBULTRA_VERSION > OS_VER_H + ptr = (u8 *)&__osPfsPifRam; +#endif + __osContLastCmd = cmd; +#if LIBULTRA_VERSION < OS_VER_I + CONT_PIFRAM_SET(__osPfsPifRam, 0, CONT_CMD_EXE); +#else + __osPfsPifRam.pifstatus = CONT_CMD_EXE; +#endif +#if LIBULTRA_VERSION < OS_VER_I + ptr = (u8 *)&__osPfsPifRam; +#endif + + requestformat.dummy = CONT_CMD_NOP; + requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX; + requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; + requestformat.cmd = cmd; + requestformat.typeh = CONT_CMD_NOP; + requestformat.typel = CONT_CMD_NOP; + requestformat.status = CONT_CMD_NOP; + requestformat.dummy1 = CONT_CMD_NOP; + + for (i = 0; i < __osMaxControllers; i++) { + *REQFORMAT(ptr) = requestformat; + ptr += sizeof(requestformat); + } + + *ptr = CONT_CMD_END; +} + +void __osPfsGetInitData(u8 *pattern, OSContStatus *data) { + u8 *ptr; + __OSContRequesFormat requestformat; + int i; + u8 bits = 0; + + ptr = (u8 *)&__osPfsPifRam; + + for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(requestformat), data++) { + requestformat = *REQFORMAT(ptr); + data->errnum = CHNL_ERR(requestformat); + + if (data->errnum != 0) { + continue; + } + + data->type = (requestformat.typel << 8) | (requestformat.typeh); + data->status = requestformat.status; + bits |= 1 << i; + } + *pattern = bits; +} diff --git a/lib/ultra/io/pfsselectbank.c b/lib/ultra/io/pfsselectbank.c new file mode 100644 index 00000000..ee3bcb54 --- /dev/null +++ b/lib/ultra/io/pfsselectbank.c @@ -0,0 +1,31 @@ +#include "PR/os_internal.h" +#include "controller.h" + +#if LIBULTRA_VERSION >= OS_VER_J +s32 __osPfsSelectBank(OSPfs* pfs, u8 bank) +#else +s32 __osPfsSelectBank(OSPfs *pfs) +#endif +{ + u8 temp[BLOCKSIZE]; + int i; + s32 ret = 0; + + for (i = 0; i < BLOCKSIZE; i++) { +#if LIBULTRA_VERSION >= OS_VER_J + temp[i] = bank; +#else + temp[i] = pfs->activebank; +#endif + } + + ret = __osContRamWrite(pfs->queue, pfs->channel, CONT_BLOCK_DETECT, temp, FALSE); + +#if LIBULTRA_VERSION >= OS_VER_J + if (ret == 0) { + pfs->activebank = bank; + } +#endif + + return ret; +} diff --git a/lib/ultra/io/piacs.c b/lib/ultra/io/piacs.c new file mode 100644 index 00000000..21cb1ec3 --- /dev/null +++ b/lib/ultra/io/piacs.c @@ -0,0 +1,24 @@ +#include "PR/os_internal.h" +#include "macros.h" + +FORCE_BSS OSMesg osPiMesgBuff[1]; +ALIGNED8 OSMesgQueue __osPiAccessQueue; +u32 __osPiAccessQueueEnabled = FALSE; + +void __osPiCreateAccessQueue(void) { + __osPiAccessQueueEnabled = TRUE; + osCreateMesgQueue(&__osPiAccessQueue, &osPiMesgBuff[0], 1); + osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK); +} + +void __osPiGetAccess(void) { + OSMesg dummyMesg; + if (!__osPiAccessQueueEnabled) { + __osPiCreateAccessQueue(); + } + osRecvMesg(&__osPiAccessQueue, &dummyMesg, OS_MESG_BLOCK); +} + +void __osPiRelAccess(void) { + osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK); +} diff --git a/lib/ultra/io/pidma.c b/lib/ultra/io/pidma.c new file mode 100644 index 00000000..b93f7b48 --- /dev/null +++ b/lib/ultra/io/pidma.c @@ -0,0 +1,32 @@ +#include "piint.h" + +s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *dramAddr, size_t size, OSMesgQueue *mq) { + register s32 ret; + + if (!__osPiDevMgr.active) { + return -1; + } + + if (direction == OS_READ) { + mb->hdr.type = OS_MESG_TYPE_DMAREAD; + } else { + mb->hdr.type = OS_MESG_TYPE_DMAWRITE; + } + + mb->hdr.pri = priority; + mb->hdr.retQueue = mq; + mb->dramAddr = dramAddr; + mb->devAddr = devAddr; + mb->size = size; +#if LIBULTRA_VERSION > OS_VER_D + mb->piHandle = NULL; +#endif + + if (priority == OS_MESG_PRI_HIGH) { + ret = osJamMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); + } else { + ret = osSendMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); + } + + return ret; +} diff --git a/lib/src/osPiGetCmdQueue.c b/lib/ultra/io/pigetcmdq.c similarity index 83% rename from lib/src/osPiGetCmdQueue.c rename to lib/ultra/io/pigetcmdq.c index ebe4cc6c..3606701a 100644 --- a/lib/src/osPiGetCmdQueue.c +++ b/lib/ultra/io/pigetcmdq.c @@ -1,4 +1,4 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "piint.h" OSMesgQueue *osPiGetCmdQueue(void) { diff --git a/lib/src/piint.h b/lib/ultra/io/piint.h similarity index 93% rename from lib/src/piint.h rename to lib/ultra/io/piint.h index 335abddc..d43ea128 100644 --- a/lib/src/piint.h +++ b/lib/ultra/io/piint.h @@ -1,5 +1,6 @@ -#ifndef _PIINT_H -#define _PIINT_H +#ifndef _PIINT_H_ +#define _PIINT_H_ + #include "PR/os_internal.h" #include "PR/rcp.h" #include "PR/os_pi.h" @@ -88,15 +89,15 @@ #define LEO_CMD_TYPE_2 2 //TODO: name #define LEO_ERROR_GOOD 0 -#define LEO_ERROR_3 3 // +#define LEO_ERROR_3 3 #define LEO_ERROR_4 4 //maybe busy? -#define LEO_ERROR_6 6 // -#define LEO_ERROR_17 17 // +#define LEO_ERROR_6 6 +#define LEO_ERROR_17 17 #define LEO_ERROR_22 22 // #define LEO_ERROR_23 23 //unrecovered read error? #define LEO_ERROR_24 24 //no reference position found? #define LEO_ERROR_29 29 // -#define LEO_ERROR_75 75 // +#define LEO_ERROR_75 75 extern OSDevMgr __osPiDevMgr; extern OSPiHandle *__osCurrentHandle[2]; @@ -110,16 +111,22 @@ void __osDevMgrMain(void *); void __osPiCreateAccessQueue(void); void __osPiRelAccess(void); void __osPiGetAccess(void); +// These functions had underscores before being removed in 2.0J +s32 osPiRawStartDma(s32, u32, void *, size_t); +s32 osPiRawReadIo(u32, u32 *); +s32 osEPiRawWriteIo(OSPiHandle *, u32 , u32); +s32 osEPiRawReadIo(OSPiHandle *, u32 , u32 *); +s32 osEPiRawStartDma(OSPiHandle *, s32, u32, void *, size_t); OSMesgQueue *osPiGetCmdQueue(void); -#define OS_RAMROM_STACKSIZE 1024 +s32 __osLeoInterrupt(void); #define WAIT_ON_IO_BUSY(stat) \ stat = IO_READ(PI_STATUS_REG); \ while (stat & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) \ stat = IO_READ(PI_STATUS_REG); -#ifdef VERSION_EU +#if LIBULTRA_VERSION == OS_VER_F #define WAIT_ON_LEO_IO_BUSY(stat) \ stat = IO_READ(PI_STATUS_REG); \ while (stat & PI_STATUS_IO_BUSY) \ @@ -132,7 +139,7 @@ OSMesgQueue *osPiGetCmdQueue(void); if (cHandle->var != pihandle->var) \ IO_WRITE(reg, pihandle->var); -#ifdef VERSION_CN +#if LIBULTRA_VERSION >= OS_VER_J #define EPI_SYNC(pihandle, stat, domain) \ \ WAIT_ON_IO_BUSY(stat) \ diff --git a/lib/ultra/io/pimgr.c b/lib/ultra/io/pimgr.c new file mode 100644 index 00000000..391d8143 --- /dev/null +++ b/lib/ultra/io/pimgr.c @@ -0,0 +1,67 @@ +#include "PR/os_internal.h" +#include "PR/rdb.h" +#include "piint.h" +#include "macros.h" + +FORCE_BSS ALIGNED8 OSThread piThread; +FORCE_BSS ALIGNED16 u8 piMgrStack[OS_PIM_STACKSIZE]; +FORCE_BSS ALIGNED8 OSMesgQueue piEventQueue; +FORCE_BSS OSMesg piEventBuf[1]; + +OSDevMgr __osPiDevMgr = { 0 }; +#if LIBULTRA_VERSION >= OS_VER_F +OSPiHandle *__osPiTable = NULL; +#endif +#if LIBULTRA_VERSION >= OS_VER_J +ALIGNED8 OSPiHandle __Dom1SpeedParam; +ALIGNED8 OSPiHandle __Dom2SpeedParam; +OSPiHandle *__osCurrentHandle[2] = { &__Dom1SpeedParam, &__Dom2SpeedParam }; +#elif LIBULTRA_VERSION >= OS_VER_H +extern OSPiHandle CartRomHandle; +extern OSPiHandle LeoDiskHandle; +OSPiHandle *__osCurrentHandle[2] = { &CartRomHandle, &LeoDiskHandle }; +#endif + +void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt) { + u32 savedMask; + OSPri oldPri; + OSPri myPri; + + if (__osPiDevMgr.active) { + return; + } + osCreateMesgQueue(cmdQ, cmdBuf, cmdMsgCnt); + osCreateMesgQueue(&piEventQueue, (OSMesg*) piEventBuf, 1); + + if (!__osPiAccessQueueEnabled) { + __osPiCreateAccessQueue(); + } + + osSetEventMesg(OS_EVENT_PI, &piEventQueue, (OSMesg) 0x22222222); + oldPri = -1; + myPri = osGetThreadPri(NULL); + + if (myPri < pri) { + oldPri = myPri; + osSetThreadPri(NULL, pri); + } + + savedMask = __osDisableInt(); + __osPiDevMgr.active = TRUE; + __osPiDevMgr.thread = &piThread; + __osPiDevMgr.cmdQueue = cmdQ; + __osPiDevMgr.evtQueue = &piEventQueue; + __osPiDevMgr.acsQueue = &__osPiAccessQueue; + __osPiDevMgr.dma = osPiRawStartDma; +#if LIBULTRA_VERSION >= OS_VER_F + __osPiDevMgr.edma = osEPiRawStartDma; +#endif + osCreateThread(&piThread, 0, __osDevMgrMain, &__osPiDevMgr, &piMgrStack[OS_PIM_STACKSIZE], pri); + osStartThread(&piThread); + + __osRestoreInt(savedMask); + + if (oldPri != -1) { + osSetThreadPri(NULL, oldPri); + } +} diff --git a/lib/src/osPiRawStartDma.c b/lib/ultra/io/pirawdma.c similarity index 53% rename from lib/src/osPiRawStartDma.c rename to lib/ultra/io/pirawdma.c index 347d1dac..c3b2fa75 100644 --- a/lib/src/osPiRawStartDma.c +++ b/lib/ultra/io/pirawdma.c @@ -1,17 +1,14 @@ -#include "libultra_internal.h" -#include "PR/rcp.h" #include "piint.h" -s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size) { - register u32 status; +s32 osPiRawStartDma(s32 direction, u32 devAddr, void *dramAddr, size_t size) { + register u32 stat; - WAIT_ON_IO_BUSY(status); + WAIT_ON_IO_BUSY(stat); - IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dram_addr)); + IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr)); + IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((uintptr_t) osRomBase | devAddr)); - IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((uintptr_t) osRomBase | cart_addr)); - - switch (dir) { + switch (direction) { case OS_READ: IO_WRITE(PI_WR_LEN_REG, size - 1); break; diff --git a/lib/ultra/io/pirawread.c b/lib/ultra/io/pirawread.c new file mode 100644 index 00000000..6ee1393f --- /dev/null +++ b/lib/ultra/io/pirawread.c @@ -0,0 +1,10 @@ +#include "piint.h" + +s32 osPiRawReadIo(u32 devAddr, u32 *data) { + register u32 stat; + + WAIT_ON_IO_BUSY(stat); + *data = IO_READ((uintptr_t) osRomBase | devAddr); + + return 0; +} diff --git a/lib/ultra/io/si.c b/lib/ultra/io/si.c new file mode 100644 index 00000000..19edfafa --- /dev/null +++ b/lib/ultra/io/si.c @@ -0,0 +1,12 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +s32 __osSiDeviceBusy() { + register u32 stat = IO_READ(SI_STATUS_REG); + + if (stat & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) { + return TRUE; + } + + return FALSE; +} diff --git a/lib/ultra/io/siacs.c b/lib/ultra/io/siacs.c new file mode 100644 index 00000000..2d401a97 --- /dev/null +++ b/lib/ultra/io/siacs.c @@ -0,0 +1,24 @@ +#include "PR/os_internal.h" +#include "macros.h" + +FORCE_BSS OSMesg osSiMesgBuff[1]; +ALIGNED8 OSMesgQueue __osSiAccessQueue; +u32 __osSiAccessQueueEnabled = FALSE; + +void __osSiCreateAccessQueue() { + __osSiAccessQueueEnabled = TRUE; + osCreateMesgQueue(&__osSiAccessQueue, &osSiMesgBuff[0], 1); + osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); +} + +void __osSiGetAccess(void) { + OSMesg dummyMesg; + if (!__osSiAccessQueueEnabled) { + __osSiCreateAccessQueue(); + } + osRecvMesg(&__osSiAccessQueue, &dummyMesg, OS_MESG_BLOCK); +} + +void __osSiRelAccess(void) { + osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); +} diff --git a/lib/ultra/io/sirawdma.c b/lib/ultra/io/sirawdma.c new file mode 100644 index 00000000..112a08e1 --- /dev/null +++ b/lib/ultra/io/sirawdma.c @@ -0,0 +1,45 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#define PIF_RAM_SIZE (PIF_RAM_END + 1 - PIF_RAM_START) + +s32 __osSiRawStartDma(s32 direction, void *dramAddr) { +#if LIBULTRA_VERSION >= OS_VER_J + if (IO_READ(SI_STATUS_REG) & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) { + return -1; + } +#else + if (__osSiDeviceBusy()) { + return -1; + } +#endif + + if (direction == OS_WRITE) { + osWritebackDCache(dramAddr, PIF_RAM_SIZE); + } + + IO_WRITE(SI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr)); + + if (direction == OS_READ) { +#ifdef BBPLAYER + if (__osBbIsBb) { + register u32 mask = __osDisableInt(); + + skKeepAlive(); + + __osRestoreInt(mask); + } +#endif + IO_WRITE(SI_PIF_ADDR_RD64B_REG, PIF_RAM_START); + } else { + IO_WRITE(SI_PIF_ADDR_WR64B_REG, PIF_RAM_START); + } + + if (direction == OS_READ) { + osInvalDCache(dramAddr, PIF_RAM_SIZE); + } + return 0; +} diff --git a/lib/src/__osSiRawReadIo.c b/lib/ultra/io/sirawread.c similarity index 84% rename from lib/src/__osSiRawReadIo.c rename to lib/ultra/io/sirawread.c index 288d9411..2010bf8a 100644 --- a/lib/src/__osSiRawReadIo.c +++ b/lib/ultra/io/sirawread.c @@ -1,10 +1,11 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/rcp.h" s32 __osSiRawReadIo(u32 devAddr, u32 *data) { if (__osSiDeviceBusy()) { return -1; } + *data = IO_READ(devAddr); return 0; } diff --git a/lib/src/__osSiRawWriteIo.c b/lib/ultra/io/sirawwrite.c similarity index 84% rename from lib/src/__osSiRawWriteIo.c rename to lib/ultra/io/sirawwrite.c index 0cec9443..96d1178a 100644 --- a/lib/src/__osSiRawWriteIo.c +++ b/lib/ultra/io/sirawwrite.c @@ -1,10 +1,11 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/rcp.h" s32 __osSiRawWriteIo(u32 devAddr, u32 data) { if (__osSiDeviceBusy()) { return -1; } + IO_WRITE(devAddr, data); return 0; } diff --git a/lib/ultra/io/sp.c b/lib/ultra/io/sp.c new file mode 100644 index 00000000..73f81a80 --- /dev/null +++ b/lib/ultra/io/sp.c @@ -0,0 +1,14 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "PR/sptask.h" +#include "../os/osint.h" + +s32 __osSpDeviceBusy() { + register u32 stat = IO_READ(SP_STATUS_REG); + + if (stat & (SP_STATUS_DMA_BUSY | SP_STATUS_DMA_FULL | SP_STATUS_IO_FULL)) { + return TRUE; + } + + return FALSE; +} diff --git a/lib/src/__osSpGetStatus.c b/lib/ultra/io/spgetstat.c similarity index 72% rename from lib/src/__osSpGetStatus.c rename to lib/ultra/io/spgetstat.c index 2e25d140..97751ec9 100644 --- a/lib/src/__osSpGetStatus.c +++ b/lib/ultra/io/spgetstat.c @@ -1,4 +1,4 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/rcp.h" u32 __osSpGetStatus() { diff --git a/lib/ultra/io/sprawdma.c b/lib/ultra/io/sprawdma.c new file mode 100644 index 00000000..8f40dfda --- /dev/null +++ b/lib/ultra/io/sprawdma.c @@ -0,0 +1,20 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "../os/osint.h" + +s32 __osSpRawStartDma(s32 dir, u32 devAddr, void *dramAddr, size_t size) { + if (__osSpDeviceBusy()) { + return -1; + } + + IO_WRITE(SP_MEM_ADDR_REG, devAddr); + IO_WRITE(SP_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr)); + + if (dir == 0) { + IO_WRITE(SP_WR_LEN_REG, size - 1); + } else { + IO_WRITE(SP_RD_LEN_REG, size - 1); + } + + return 0; +} diff --git a/lib/ultra/io/spsetpc.c b/lib/ultra/io/spsetpc.c new file mode 100644 index 00000000..7d23cd3d --- /dev/null +++ b/lib/ultra/io/spsetpc.c @@ -0,0 +1,13 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +s32 __osSpSetPc(u32 pc) { + register u32 status = IO_READ(SP_STATUS_REG); + + if (!(status & SP_STATUS_HALT)) { + return -1; + } + IO_WRITE(SP_PC_REG, pc); + + return 0; +} diff --git a/lib/ultra/io/spsetstat.c b/lib/ultra/io/spsetstat.c new file mode 100644 index 00000000..8c8ecff8 --- /dev/null +++ b/lib/ultra/io/spsetstat.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +void __osSpSetStatus(u32 data) { + IO_WRITE(SP_STATUS_REG, data); +} diff --git a/lib/ultra/io/sptask.c b/lib/ultra/io/sptask.c new file mode 100644 index 00000000..b08d2e93 --- /dev/null +++ b/lib/ultra/io/sptask.c @@ -0,0 +1,65 @@ +#include "PR/os_internal.h" +#include "PR/sptask.h" +#include "PR/rcp.h" +#include "../os/osint.h" +#include "macros.h" + +#define _osVirtualToPhysical(ptr) \ + if (ptr != NULL) { \ + ptr = (void *) osVirtualToPhysical(ptr); \ + } + +FORCE_BSS static OSTask tmpTask; + +static OSTask *_VirtualToPhysicalTask(OSTask *intp) { + OSTask *tp; + tp = &tmpTask; + bcopy(intp, tp, sizeof(OSTask)); + + _osVirtualToPhysical(tp->t.ucode); + _osVirtualToPhysical(tp->t.ucode_data); + _osVirtualToPhysical(tp->t.dram_stack); + _osVirtualToPhysical(tp->t.output_buff); + _osVirtualToPhysical(tp->t.output_buff_size); + _osVirtualToPhysical(tp->t.data_ptr); + _osVirtualToPhysical(tp->t.yield_data_ptr); + return tp; +} + +void osSpTaskLoad(OSTask *intp) { + OSTask *tp; + tp = _VirtualToPhysicalTask(intp); + + if (tp->t.flags & OS_TASK_YIELDED) { + tp->t.ucode_data = tp->t.yield_data_ptr; + tp->t.ucode_data_size = tp->t.yield_data_size; + intp->t.flags &= ~OS_TASK_YIELDED; +#if LIBULTRA_VERSION >= OS_VER_H + if (tp->t.flags & OS_TASK_LOADABLE) { + tp->t.ucode = (u64 *) IO_READ((uintptr_t)intp->t.yield_data_ptr + OS_YIELD_DATA_SIZE_EX - sizeof(uintptr_t)); + } +#endif + } + + osWritebackDCache(tp, sizeof(OSTask)); + __osSpSetStatus(SP_CLR_YIELD | SP_CLR_YIELDED | SP_CLR_TASKDONE | SP_SET_INTR_BREAK); + + while (__osSpSetPc(SP_IMEM_START) == -1) { + } + + while (__osSpRawStartDma(1, (SP_IMEM_START - sizeof(*tp)), tp, sizeof(OSTask)) == -1) { + } + + while (__osSpDeviceBusy()) { + } + + while (__osSpRawStartDma(1, SP_IMEM_START, tp->t.ucode_boot, tp->t.ucode_boot_size) == -1) { + } +} + +void osSpTaskStartGo(UNUSED OSTask *tp) { + while (__osSpDeviceBusy()) { + } + + __osSpSetStatus(SP_SET_INTR_BREAK | SP_CLR_SSTEP | SP_CLR_BROKE | SP_CLR_HALT); +} diff --git a/lib/ultra/io/sptaskyield.c b/lib/ultra/io/sptaskyield.c new file mode 100644 index 00000000..78bacaee --- /dev/null +++ b/lib/ultra/io/sptaskyield.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +void osSpTaskYield(void) { + __osSpSetStatus(SP_SET_YIELD); +} diff --git a/lib/ultra/io/sptaskyielded.c b/lib/ultra/io/sptaskyielded.c new file mode 100644 index 00000000..38107059 --- /dev/null +++ b/lib/ultra/io/sptaskyielded.c @@ -0,0 +1,18 @@ +#include "PR/os_internal.h" +#include "PR/sptask.h" +#include "PR/rcp.h" + +OSYieldResult osSpTaskYielded(OSTask *tp) { + s32 status; + u32 result; + + status = __osSpGetStatus(); + result = (status & SP_STATUS_YIELDED) ? OS_TASK_YIELDED : 0; + + if (status & SP_STATUS_YIELD) { + tp->t.flags |= result; + tp->t.flags &= ~(OS_TASK_DP_WAIT); + } + + return result; +} diff --git a/lib/ultra/io/vi.c b/lib/ultra/io/vi.c new file mode 100644 index 00000000..bdc2446d --- /dev/null +++ b/lib/ultra/io/vi.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +ALIGNED8 __OSViContext vi[2] = { 0 }; +__OSViContext *__osViCurr = &vi[0]; +__OSViContext *__osViNext = &vi[1]; + +#if LIBULTRA_VERSION == OS_VER_E || LIBULTRA_VERSION == OS_VER_F +u32 osViClock = VI_NTSC_CLOCK; +u32 osIsNtscEnabled = FALSE; // OS_TV_PAL +#elif LIBULTRA_VERSION == OS_VER_D +u32 osIsNtscEnabled = TRUE; // OS_TV_NTSC +u32 osViClock = VI_NTSC_CLOCK; +#endif + +void __osViInit(void) { +#if LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION >= 1 + osIsNtscEnabled = osTvType; +#endif + + bzero(vi, sizeof(vi)); + __osViCurr = &vi[0]; + __osViNext = &vi[1]; + __osViNext->retraceCount = 1; + __osViCurr->retraceCount = 1; + +#if LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION == 0 + if (osIsNtscEnabled != FALSE) { + __osViNext->modep = &osViModeNtscLan1; + osViClock = VI_NTSC_CLOCK; + } else { + __osViNext->modep = &osViModePalLan1; + osViClock = VI_PAL_CLOCK; + } +#elif LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION >= 1 + if (osIsNtscEnabled == TRUE) { + __osViNext->modep = &osViModeNtscLan1; + osViClock = VI_NTSC_CLOCK; + } else { + __osViNext->modep = &osViModePalLan1; + osViClock = VI_MPAL_CLOCK; + } +#elif LIBULTRA_VERSION == OS_VER_E || LIBULTRA_VERSION == OS_VER_F + if (osTvType == OS_TV_PAL) { + __osViNext->modep = &osViModePalLan1; + osViClock = VI_PAL_CLOCK; + } else if (osTvType == OS_TV_MPAL) { + __osViNext->modep = &osViModeMpalLan1; + osViClock = VI_MPAL_CLOCK; + } else { + __osViNext->modep = &osViModeNtscLan1; + osViClock = VI_NTSC_CLOCK; + } +#else + __osViNext->framep = (void *) K0BASE; + __osViCurr->framep = (void *) K0BASE; + if (osTvType == OS_TV_PAL) { + __osViNext->modep = &osViModePalLan1; + } else if (osTvType == OS_TV_MPAL) { + __osViNext->modep = &osViModeMpalLan1; + } else { + __osViNext->modep = &osViModeNtscLan1; + } +#endif + __osViNext->state = VI_STATE_BLACK; + __osViNext->control = __osViNext->modep->comRegs.ctrl; + +#if LIBULTRA_VERSION > OS_VER_D || (LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION >= 1) + while (IO_READ(VI_CURRENT_REG) > 10) { //wait for vsync? + } + + IO_WRITE(VI_STATUS_REG, 0); //pixel size blank (no data, no sync) +#endif + __osViSwapContext(); +} diff --git a/lib/ultra/io/viblack.c b/lib/ultra/io/viblack.c new file mode 100644 index 00000000..98efbb6f --- /dev/null +++ b/lib/ultra/io/viblack.c @@ -0,0 +1,13 @@ +#include "PR/os_internal.h" + +void osViBlack(u8 active) { + register u32 saveMask = __osDisableInt(); + + if (active) { + __osViNext->state |= VI_STATE_BLACK; + } else { + __osViNext->state &= ~VI_STATE_BLACK; + } + + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/io/vigetcurrcontext.c b/lib/ultra/io/vigetcurrcontext.c new file mode 100644 index 00000000..31602d60 --- /dev/null +++ b/lib/ultra/io/vigetcurrcontext.c @@ -0,0 +1,5 @@ +#include "PR/os_internal.h" + +__OSViContext *__osViGetCurrentContext(void) { + return __osViCurr; +} diff --git a/lib/ultra/io/vimgr.c b/lib/ultra/io/vimgr.c new file mode 100644 index 00000000..5cdb34d5 --- /dev/null +++ b/lib/ultra/io/vimgr.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include "../os/osint.h" + +OSDevMgr __osViDevMgr = { 0 }; +#if LIBULTRA_VERSION >= OS_VER_J +u32 __additional_scanline = 0; +#endif +static OSThread viThread; +static ALIGNED16 u8 viMgrStack[OS_VIM_STACKSIZE]; +static OSMesgQueue viEventQueue; +static ALIGNED8 OSMesg viMgrMesgBuff[5]; +static ALIGNED8 OSIoMesg viRetraceMsg; +static ALIGNED8 OSIoMesg viCounterMsg; + +static void viMgrMain(void *arg); + +void osCreateViManager(OSPri pri) { + u32 savedMask; + OSPri oldPri; + OSPri myPri; + + if (!__osViDevMgr.active) { + __osTimerServicesInit(); +#if LIBULTRA_VERSION >= OS_VER_J + __additional_scanline = 0; +#endif + osCreateMesgQueue(&viEventQueue, &viMgrMesgBuff[0], ARRAY_COUNT(viMgrMesgBuff)); + viRetraceMsg.hdr.type = OS_MESG_TYPE_VRETRACE; + viRetraceMsg.hdr.pri = OS_MESG_PRI_NORMAL; + viRetraceMsg.hdr.retQueue = NULL; + viCounterMsg.hdr.type = OS_MESG_TYPE_COUNTER; + viCounterMsg.hdr.pri = OS_MESG_PRI_NORMAL; + viCounterMsg.hdr.retQueue = NULL; + osSetEventMesg(OS_EVENT_VI, &viEventQueue, &viRetraceMsg); + osSetEventMesg(OS_EVENT_COUNTER, &viEventQueue, &viCounterMsg); + oldPri = -1; + myPri = osGetThreadPri(NULL); + + if (myPri < pri) { + oldPri = myPri; + osSetThreadPri(NULL, pri); + } + + savedMask = __osDisableInt(); + __osViDevMgr.active = TRUE; + __osViDevMgr.thread = &viThread; + __osViDevMgr.cmdQueue = &viEventQueue; + __osViDevMgr.evtQueue = &viEventQueue; + __osViDevMgr.acsQueue = NULL; + __osViDevMgr.dma = NULL; +#if LIBULTRA_VERSION > OS_VER_D + __osViDevMgr.edma = NULL; +#endif + osCreateThread(&viThread, 0, viMgrMain, (void *) &__osViDevMgr, &viMgrStack[OS_VIM_STACKSIZE], pri); + __osViInit(); + osStartThread(&viThread); + __osRestoreInt(savedMask); + + if (oldPri != -1) { + osSetThreadPri(NULL, oldPri); + } + } +} + +static void viMgrMain(void *arg) { + __OSViContext *vc; + OSDevMgr *dm; + OSIoMesg *mb; + static u16 retrace; + u32 first; + u32 count; + + mb = NULL; + first = FALSE; + vc = __osViGetCurrentContext(); + retrace = vc->retraceCount; + if (retrace == 0) { + retrace = 1; + } + dm = (OSDevMgr *) arg; + + while (TRUE) { + osRecvMesg(dm->evtQueue, (OSMesg)&mb, OS_MESG_BLOCK); + switch (mb->hdr.type) { + case OS_MESG_TYPE_VRETRACE: + __osViSwapContext(); + retrace--; + + if (retrace == 0) { + vc = __osViGetCurrentContext(); + if (vc->msgq != NULL) { + osSendMesg(vc->msgq, vc->msg, OS_MESG_NOBLOCK); + } + retrace = vc->retraceCount; + } + + __osViIntrCount++; + + if (first) { + count = osGetCount(); + __osCurrentTime = count; + first = 0; + } + + count = __osBaseCounter; + __osBaseCounter = osGetCount(); + count = __osBaseCounter - count; + __osCurrentTime = __osCurrentTime + count; + break; + + case OS_MESG_TYPE_COUNTER: + __osTimerInterrupt(); + break; + } + } +} diff --git a/lib/ultra/io/visetevent.c b/lib/ultra/io/visetevent.c new file mode 100644 index 00000000..984019e3 --- /dev/null +++ b/lib/ultra/io/visetevent.c @@ -0,0 +1,10 @@ +#include "PR/os_internal.h" + +void osViSetEvent(OSMesgQueue *mq, OSMesg m, u32 retraceCount) { + register u32 saveMask = __osDisableInt(); + + __osViNext->msgq = mq; + __osViNext->msg = m; + __osViNext->retraceCount = retraceCount; + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/io/visetmode.c b/lib/ultra/io/visetmode.c new file mode 100644 index 00000000..be766532 --- /dev/null +++ b/lib/ultra/io/visetmode.c @@ -0,0 +1,20 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +void osViSetMode(OSViMode *modep) { + register u32 saveMask = __osDisableInt(); + +#ifdef BBPLAYER + if (__osBbIsBb) { + modep->comRegs.ctrl &= ~VI_CTRL_PIXEL_ADV_2; + } +#endif + + __osViNext->modep = modep; + __osViNext->state = VI_STATE_MODE_UPDATED; + __osViNext->control = __osViNext->modep->comRegs.ctrl; + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/io/visetspecial.c b/lib/ultra/io/visetspecial.c new file mode 100644 index 00000000..d9f21efb --- /dev/null +++ b/lib/ultra/io/visetspecial.c @@ -0,0 +1,44 @@ +#include +#include + +void osViSetSpecialFeatures(u32 func) { + register u32 saveMask = __osDisableInt(); + + if (func & OS_VI_GAMMA_ON) { + __osViNext->control |= VI_CTRL_GAMMA_ON; + } + + if (func & OS_VI_GAMMA_OFF) { + __osViNext->control &= ~VI_CTRL_GAMMA_ON; + } + + if (func & OS_VI_GAMMA_DITHER_ON) { + __osViNext->control |= VI_CTRL_GAMMA_DITHER_ON; + } + + if (func & OS_VI_GAMMA_DITHER_OFF) { + __osViNext->control &= ~VI_CTRL_GAMMA_DITHER_ON; + } + + if (func & OS_VI_DIVOT_ON) { + __osViNext->control |= VI_CTRL_DIVOT_ON; + } + + if (func & OS_VI_DIVOT_OFF) { + __osViNext->control &= ~VI_CTRL_DIVOT_ON; + } + + if (func & OS_VI_DITHER_FILTER_ON) { + __osViNext->control |= VI_CTRL_DITHER_FILTER_ON; + __osViNext->control &= ~VI_CTRL_ANTIALIAS_MASK; + } + + if (func & OS_VI_DITHER_FILTER_OFF) { + __osViNext->control &= ~VI_CTRL_DITHER_FILTER_ON; + __osViNext->control |= __osViNext->modep->comRegs.ctrl & VI_CTRL_ANTIALIAS_MASK; + } + + __osViNext->state |= VI_STATE_CTRL_UPDATED; + + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/io/viswapbuf.c b/lib/ultra/io/viswapbuf.c new file mode 100644 index 00000000..3751da56 --- /dev/null +++ b/lib/ultra/io/viswapbuf.c @@ -0,0 +1,9 @@ +#include "PR/os_internal.h" + +void osViSwapBuffer(void *frameBufPtr) { + u32 saveMask = __osDisableInt(); + + __osViNext->framep = frameBufPtr; + __osViNext->state |= VI_STATE_BUFFER_UPDATED; + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/io/viswapcontext.c b/lib/ultra/io/viswapcontext.c new file mode 100644 index 00000000..9bd3570b --- /dev/null +++ b/lib/ultra/io/viswapcontext.c @@ -0,0 +1,76 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +void __osViSwapContext() { + register OSViMode *vm; + register __OSViContext *vc; + u32 origin; + u32 hStart; +#if LIBULTRA_VERSION >= OS_VER_J + u32 vStart; +#endif + u32 nomValue; + u32 field; + + field = 0; + vc = __osViNext; + vm = vc->modep; + + field = IO_READ(VI_CURRENT_REG) & 1; //field num + + origin = osVirtualToPhysical(vc->framep) + (vm->fldRegs[field].origin); + if (vc->state & VI_STATE_XSCALE_UPDATED) { + vc->x.scale |= (vm->comRegs.xScale & ~VI_SCALE_MASK); + } else { + vc->x.scale = vm->comRegs.xScale; + } + + if (vc->state & VI_STATE_YSCALE_UPDATED) { + nomValue = vm->fldRegs[field].yScale & VI_SCALE_MASK; + vc->y.scale = vc->y.factor * nomValue; + vc->y.scale |= vm->fldRegs[field].yScale & ~VI_SCALE_MASK; + } else { + vc->y.scale = vm->fldRegs[field].yScale; + } + +#if LIBULTRA_VERSION >= OS_VER_J + vStart = (vm->fldRegs[field].vStart - (__additional_scanline << 0x10)) + __additional_scanline; +#endif + hStart = vm->comRegs.hStart; + + if (vc->state & VI_STATE_BLACK) { + hStart = 0; + } + + if (vc->state & VI_STATE_REPEATLINE) { + vc->y.scale = 0; + origin = osVirtualToPhysical(vc->framep); + } + + if (vc->state & VI_STATE_FADE) { + vc->y.scale = (vc->y.offset << VI_SUBPIXEL_SH) & (VI_2_10_FPART_MASK << VI_SUBPIXEL_SH); + origin = osVirtualToPhysical(vc->framep); + } + + IO_WRITE(VI_ORIGIN_REG, origin); + IO_WRITE(VI_WIDTH_REG, vm->comRegs.width); + IO_WRITE(VI_BURST_REG, vm->comRegs.burst); + IO_WRITE(VI_V_SYNC_REG, vm->comRegs.vSync); + IO_WRITE(VI_H_SYNC_REG, vm->comRegs.hSync); + IO_WRITE(VI_LEAP_REG, vm->comRegs.leap); + IO_WRITE(VI_H_START_REG, hStart); +#if LIBULTRA_VERSION >= OS_VER_J + IO_WRITE(VI_V_START_REG, vStart); +#else + IO_WRITE(VI_V_START_REG, vm->fldRegs[field].vStart); +#endif + IO_WRITE(VI_V_BURST_REG, vm->fldRegs[field].vBurst); + IO_WRITE(VI_INTR_REG, vm->fldRegs[field].vIntr); + IO_WRITE(VI_X_SCALE_REG, vc->x.scale); + IO_WRITE(VI_Y_SCALE_REG, vc->y.scale); + IO_WRITE(VI_CONTROL_REG, vc->control); + + __osViNext = __osViCurr; + __osViCurr = vc; + *__osViNext = *__osViCurr; +} diff --git a/lib/ultra/io/vitbl.c b/lib/ultra/io/vitbl.c new file mode 100644 index 00000000..8b41e534 --- /dev/null +++ b/lib/ultra/io/vitbl.c @@ -0,0 +1,1750 @@ +#include "PR/os.h" +#include "PR/rcp.h" + +OSViMode osViModeTable[] = { + { + OS_VI_NTSC_LPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LAN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_LAF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_HPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_HPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_HAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_HAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_HPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_NTSC_HPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + +#if LIBULTRA_VERSION > OS_VER_D || (LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION == 0) + { + OS_VI_PAL_LPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LAN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_LAF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_HPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_HPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_HAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_HAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_HPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_PAL_HPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(93, 567), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, +#endif + +#if LIBULTRA_VERSION > OS_VER_D || (LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION >= 1) + { + OS_VI_MPAL_LPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3089, 4), // hSync + OS_VI_LEAP(3097, 3098), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3089, 4), // hSync + OS_VI_LEAP(3097, 3098), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3089, 4), // hSync + OS_VI_LEAP(3097, 3098), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LAN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3089, 4), // hSync + OS_VI_LEAP(3097, 3098), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_LAF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_HPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_HPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_HAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_HAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { //[0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { //[1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_HPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_MPAL_HPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(524), // vSync + OS_VI_HSYNC(3088, 0), // hSync + OS_VI_LEAP(3100, 3100), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(35, 509), // vStart + OS_VI_BURST(2, 2, 11, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, +#endif + +#if LIBULTRA_VERSION >= OS_VER_J + { + OS_VI_FPAL_LPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LAN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_LAF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.25), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0.75), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_HPN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_HPF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_HAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_HAF1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_SERRATE_ON | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(1280), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_HPN2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_3 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(1280), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + }, + { + OS_VI_FPAL_HPF2, // type + { // comRegs + VI_CTRL_TYPE_32 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_SERRATE_ON | VI_CTRL_ANTIALIAS_MODE_2 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(640), // width + OS_VI_BURST(58, 30, 4, 69), // burst + OS_VI_VSYNC(624), // vSync + OS_VI_HSYNC(3177, 23), // hSync + OS_VI_LEAP(3183, 3181), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(1, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(2560), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(45, 615), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(5120), // origin + OS_VI_SCALE(0.5, 0.5), // yScale + OS_VI_HSTART(47, 617), // vStart + OS_VI_BURST(105, 2, 13, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } + } +#endif +}; diff --git a/lib/ultra/ld.inc b/lib/ultra/ld.inc new file mode 100644 index 00000000..c74afbdf --- /dev/null +++ b/lib/ultra/ld.inc @@ -0,0 +1,9 @@ +#include "PR/os_version.h" + +#if LIBULTRA_VERSION >= OS_VER_K +#include "K_L.inc" +#elif LIBULTRA_VERSION >= OS_VER_F +#include "F_I.inc" +#elif LIBULTRA_VERSION >= OS_VER_D +#include "D.inc" +#endif diff --git a/lib/ultra/libc/bcopy.s b/lib/ultra/libc/bcopy.s new file mode 100644 index 00000000..ed8fca42 --- /dev/null +++ b/lib/ultra/libc/bcopy.s @@ -0,0 +1,219 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +#ifdef BBPLAYER +.set mips2 +#endif + +.text +LEAF(bcopy) + move a3, a1 + beqz a2, ret + beq a0, a1, ret + blt a1, a0, goforwards + + add v0, a0, a2 + bge a1, v0, goforwards + b gobackwards + +goforwards: + + blt a2, 16, forwards_bytecopy + + andi v0, a0, 0x3 + andi v1, a1, 0x3 + beq v0, v1,forwalignable + + +forwards_bytecopy: + beqz a2, ret + addu v1, a0, a2 +99: + lb v0, 0(a0) + addiu a0, a0, 1 + sb v0, 0(a1) + addiu a1, a1, 1 + bne a0, v1, 99b +ret: + move v0, a3 + jr ra + +forwalignable: + beqz v0, forwards + beq v0, 1, forw_copy3 + beq v0, 2, forw_copy2 + + lb v0, 0(a0) + addiu a0, a0, 1 + sb v0, 0(a1) + addiu a1, a1, 1 + addiu a2, a2, -1 + b forwards + +forw_copy2: + lh v0, 0(a0) + addiu a0, a0, 2 + sh v0, 0(a1) + addiu a1, a1, 2 + addiu a2, a2, -2 + b forwards + +forw_copy3: + lb v0, 0(a0) + lh v1, 1(a0) + addiu a0, a0, 3 + sb v0, 0(a1) + sh v1, 1(a1) + addiu a1, a1, 3 + addiu a2, a2, -3 + +forwards: +forwards_32: + blt a2, 32, forwards_16 + lw v0, 0(a0) + lw v1, 4(a0) + lw t0, 8(a0) + lw t1, 12(a0) + lw t2, 16(a0) + lw t3, 20(a0) + lw ta0, 24(a0) + lw ta1, 28(a0) + addiu a0, a0, 32 + sw v0, 0(a1) + sw v1, 4(a1) + sw t0, 8(a1) + sw t1, 12(a1) + sw t2, 16(a1) + sw t3, 20(a1) + sw ta0, 24(a1) + sw ta1, 28(a1) + addiu a1, a1, 32 + addiu a2, a2, -32 + b forwards_32 + +forwards_16: + blt a2, 16, forwards_4 + lw v0, 0(a0) + lw v1, 4(a0) + lw t0, 8(a0) + lw t1, 12(a0) + addiu a0, a0, 16 + sw v0, 0(a1) + sw v1, 4(a1) + sw t0, 8(a1) + sw t1, 12(a1) + addiu a1, a1, 16 + addiu a2, a2, -16 + b forwards_16 + +forwards_4: + blt a2, 4, forwards_bytecopy + + lw v0, 0(a0) + addiu a0, a0, 4 + sw v0, 0(a1) + addiu a1, a1, 4 + addiu a2, a2, -4 + b forwards_4 + +gobackwards: + add a0, a0,a2 + add a1, a1,a2 + blt a2, 16, backwards_bytecopy + + andi v0, a0, 0x3 + andi v1, a1, 0x3 + beq v0, v1,backalignable + +backwards_bytecopy: + beqz a2, ret + addiu a0, a0, -1 + addiu a1, a1, -1 + subu v1, a0,a2 +99: + lb v0, 0(a0) + addiu a0, a0, -1 + sb v0, 0(a1) + addiu a1, a1, -1 + bne a0, v1,99b + + move v0, a3 + jr ra +backalignable: + beqz v0, backwards + beq v0, 3, back_copy3 + beq v0, 2, back_copy2 + lb v0, -1(a0) + addiu a0, a0, -1 + sb v0, -1(a1) + addiu a1, a1, -1 + addiu a2, a2, -1 + b backwards + +back_copy2: + lh v0, -2(a0) + addiu a0, a0, -2 + sh v0, -2(a1) + addiu a1, a1, -2 + addiu a2, a2, -2 + b backwards + +back_copy3: + lb v0, -1(a0) + lh v1, -3(a0) + addiu a0, a0, -3 + sb v0, -1(a1) + sh v1, -3(a1) + addiu a1, a1, -3 + addiu a2, a2, -3 + +backwards: +backwards_32: + blt a2, 32, backwards_16 + lw v0, -4(a0) + lw v1, -8(a0) + lw t0, -12(a0) + lw t1, -16(a0) + lw t2, -20(a0) + lw t3, -24(a0) + lw ta0, -28(a0) + lw ta1, -32(a0) + addiu a0, a0, -32 + sw v0, -4(a1) + sw v1, -8(a1) + sw t0, -12(a1) + sw t1, -16(a1) + sw t2, -20(a1) + sw t3, -24(a1) + sw ta0, -28(a1) + sw ta1, -32(a1) + addiu a1, a1, -32 + addiu a2, a2, -32 + b backwards_32 + +backwards_16: + blt a2, 16, backwards_4 + lw v0, -4(a0) + lw v1, -8(a0) + lw t0, -12(a0) + lw t1, -16(a0) + addiu a0, a0, -16 + sw v0, -4(a1) + sw v1, -8(a1) + sw t0, -12(a1) + sw t1, -16(a1) + addiu a1, a1, -16 + addiu a2, a2, -16 + b backwards_16 + +backwards_4: + blt a2, 4, backwards_bytecopy + lw v0, -4(a0) + addiu a0, a0, -4 + sw v0, -4(a1) + addiu a1, a1, -4 + addiu a2, a2, -4 + b backwards_4 + +END(bcopy) diff --git a/lib/ultra/libc/bzero.s b/lib/ultra/libc/bzero.s new file mode 100644 index 00000000..c9b599f3 --- /dev/null +++ b/lib/ultra/libc/bzero.s @@ -0,0 +1,55 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(bzero) + negu v1, a0 + blt a1, 12, bytezero + + andi v1, v1, 0x3 + subu a1, a1, v1 + + beqz v1, blkzero + swl zero, 0(a0) + addu a0, a0, v1 +blkzero: + and a3, a1, ~31 + subu a1, a1, a3 + beqz a3, wordzero + + addu a3, a3, a0 +1: + sw zero, 0(a0) + sw zero, 4(a0) + sw zero, 8(a0) + sw zero, 12(a0) + addiu a0, a0, 32 + sw zero, -16(a0) + sw zero, -12(a0) + sw zero, -8(a0) + sw zero, -4(a0) + bne a0, a3, 1b + +wordzero: + and a3, a1, ~3 + subu a1, a1, a3 + beqz a3, bytezero + + addu a3, a3, a0 +1: + addiu a0, a0, 4 + sw zero, -4(a0) + bne a0, a3, 1b + +bytezero: + blez a1, zerodone + #nop + addu a1, a1, a0 +1: + addiu a0, a0, 1 + sb zero, -1(a0) + bne a0, a1, 1b +zerodone: + jr ra +END(bzero) diff --git a/lib/src/ldiv.c b/lib/ultra/libc/ldiv.c similarity index 82% rename from lib/src/ldiv.c rename to lib/ultra/libc/ldiv.c index 566ad173..fe133bdf 100644 --- a/lib/src/ldiv.c +++ b/lib/ultra/libc/ldiv.c @@ -1,14 +1,14 @@ -#include "libultra_internal.h" -#include +#include "PR/os_version.h" +#include "stdlib.h" -// for some reason the order of the functions has been swapped - -#ifdef VERSION_CN +// Function swapped from 2.0I onwards +#if LIBULTRA_VERSION >= OS_VER_I ldiv_t ldiv(long num, long denom) { ldiv_t ret; ret.quot = num / denom; ret.rem = num - denom * ret.quot; + if (ret.quot < 0 && ret.rem > 0) { ret.quot++; ret.rem -= denom; @@ -23,6 +23,7 @@ lldiv_t lldiv(long long num, long long denom) { ret.quot = num / denom; ret.rem = num - denom * ret.quot; + if (ret.quot < 0 && ret.rem > 0) { ret.quot++; ret.rem -= denom; @@ -31,12 +32,13 @@ lldiv_t lldiv(long long num, long long denom) { return ret; } -#ifndef VERSION_CN +#if LIBULTRA_VERSION < OS_VER_I ldiv_t ldiv(long num, long denom) { ldiv_t ret; ret.quot = num / denom; ret.rem = num - denom * ret.quot; + if (ret.quot < 0 && ret.rem > 0) { ret.quot++; ret.rem -= denom; diff --git a/lib/src/math/llmuldiv.c b/lib/ultra/libc/ll.c similarity index 64% rename from lib/src/math/llmuldiv.c rename to lib/ultra/libc/ll.c index 2af91aae..94549968 100644 --- a/lib/src/math/llmuldiv.c +++ b/lib/ultra/libc/ll.c @@ -1,53 +1,46 @@ -unsigned long long __ull_rshift(unsigned long long a0, unsigned long long a1) -{ +unsigned long long __ull_rshift(unsigned long long a0, unsigned long long a1) { return a0 >> a1; } -unsigned long long __ull_rem(unsigned long long a0, unsigned long long a1) -{ + +unsigned long long __ull_rem(unsigned long long a0, unsigned long long a1) { return a0 % a1; } -unsigned long long __ull_div(unsigned long long a0, unsigned long long a1) -{ + +unsigned long long __ull_div(unsigned long long a0, unsigned long long a1) { return a0 / a1; } -unsigned long long __ll_lshift(unsigned long long a0, unsigned long long a1) -{ +unsigned long long __ll_lshift(unsigned long long a0, unsigned long long a1) { return a0 << a1; } -long long __ll_rem(unsigned long long a0, long long a1) -{ +long long __ll_rem(unsigned long long a0, long long a1) { return a0 % a1; } -long long __ll_div(long long a0, long long a1) -{ +long long __ll_div(long long a0, long long a1) { return a0 / a1; } -unsigned long long __ll_mul(unsigned long long a0, unsigned long long a1) -{ +unsigned long long __ll_mul(unsigned long long a0, unsigned long long a1) { return a0 * a1; } -void __ull_divremi(unsigned long long *div, unsigned long long *rem, unsigned long long a2, unsigned short a3) -{ +void __ull_divremi(unsigned long long *div, unsigned long long *rem, unsigned long long a2, unsigned short a3) { *div = a2 / a3; *rem = a2 % a3; } -long long __ll_mod(long long a0, long long a1) -{ - long long tmp = a0 % a1; - if ((tmp < 0 && a1 > 0) || (tmp > 0 && a1 < 0)) - { +long long __ll_mod(long long a0, long long a1) { + long long tmp = a0 % a1; + + if ((tmp < 0 && a1 > 0) || (tmp > 0 && a1 < 0)) { tmp += a1; } + return tmp; } -long long __ll_rshift(long long a0, long long a1) -{ +long long __ll_rshift(long long a0, long long a1) { return a0 >> a1; } diff --git a/lib/ultra/libc/llcvt.c b/lib/ultra/libc/llcvt.c new file mode 100644 index 00000000..2c423dd8 --- /dev/null +++ b/lib/ultra/libc/llcvt.c @@ -0,0 +1,31 @@ +long long __d_to_ll(double d) { + return d; +} + +long long __f_to_ll(float f) { + return f; +} + +unsigned long long __d_to_ull(double d) { + return d; +} + +unsigned long long __f_to_ull(float f) { + return f; +} + +double __ll_to_d(long long s) { + return s; +} + +float __ll_to_f(long long s) { + return s; +} + +double __ull_to_d(unsigned long long u) { + return u; +} + +float __ull_to_f(unsigned long long u) { + return u; +} diff --git a/lib/ultra/libc/sprintf.c b/lib/ultra/libc/sprintf.c new file mode 100644 index 00000000..da48bfa5 --- /dev/null +++ b/lib/ultra/libc/sprintf.c @@ -0,0 +1,22 @@ +#include +#include +#include "xstdio.h" + +static char *proutSprintf(char *dst, const char *src, size_t count); + +int sprintf(char *dst, const char *fmt, ...) +{ + s32 ans; + va_list ap; + va_start(ap, fmt); + ans = _Printf(proutSprintf, dst, fmt, ap); + if (ans >= 0) + { + dst[ans] = 0; + } + return ans; +} +static char *proutSprintf(char *dst, const char *src, size_t count) +{ + return (char *)memcpy((u8 *)dst, (u8 *)src, count) + count; +} diff --git a/lib/ultra/libc/string.c b/lib/ultra/libc/string.c new file mode 100644 index 00000000..2bd09550 --- /dev/null +++ b/lib/ultra/libc/string.c @@ -0,0 +1,55 @@ +#include "PR/os_version.h" +#include + +// Functions swapped from 2.0I onwards +#if LIBULTRA_VERSION >= OS_VER_I +char *strchr(const char *s, int c) { + char ch = c; + while (*s != ch) { + if (*s == 0) { + return NULL; + } + s++; + } + return (char *) s; +} + +size_t strlen(const char *s) { + const char *sc = s; + while (*sc) { + sc++; + } + return sc - s; +} +#endif + +void *memcpy(void *dst, const void *src, size_t size) { + u8 *_dst = dst; + const u8 *_src = src; + while (size > 0) { + *_dst++ = *_src++; + size--; + } + return dst; +} + +#if LIBULTRA_VERSION < OS_VER_I +size_t strlen(const char *s) { + const unsigned char *sc = (const unsigned char *) s; + while (*sc) { + sc++; + } + return (const char *) sc - s; +} + +char *strchr(const char *s, int c) { + unsigned char ch = c; + while (*(unsigned char *)s != ch) { + if (*(unsigned char *)s == 0) { + return NULL; + } + s++; + } + return (char *) s; +} +#endif diff --git a/lib/ultra/libc/syncprintf.c b/lib/ultra/libc/syncprintf.c new file mode 100644 index 00000000..123b1799 --- /dev/null +++ b/lib/ultra/libc/syncprintf.c @@ -0,0 +1,21 @@ +#include "stdarg.h" +#include "macros.h" + +#if LIBULTRA_VERSION >= OS_VER_J +void __osSyncVPrintf(UNUSED const char *fmt, UNUSED va_list args) { + // these functions intentionally left blank. ifdeffed out in rom release +} +#endif + +#if LIBULTRA_VERSION > OS_VER_D +void osSyncPrintf(UNUSED const char *fmt, ...) { + UNUSED int ans; + UNUSED va_list ap; + // these functions intentionally left blank. ifdeffed out in rom release +} + +void rmonPrintf(UNUSED const char *fmt, ...) { + UNUSED int ans; + UNUSED va_list ap; +} +#endif diff --git a/lib/ultra/libc/xldtob.c b/lib/ultra/libc/xldtob.c new file mode 100644 index 00000000..3afc36fb --- /dev/null +++ b/lib/ultra/libc/xldtob.c @@ -0,0 +1,300 @@ +#include +#include +#include "xstdio.h" + +#define BUFF_LEN 0x20 + +static s16 _Ldunscale(s16* pex, _Pft* px); +static void _Genld(_Pft* px, char_x code, u8* p, s16 nsig, s16 xexp); + +static const double pows[] = {10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L}; + +// float properties +#define _D0 0 +#define _DBIAS 0x3ff +#define _DLONG 1 +#define _DOFF 4 +#define _FBIAS 0x7e +#define _FOFF 7 +#define _FRND 1 +#define _LBIAS 0x3ffe +#define _LOFF 15 +// integer properties +#define _C2 1 +#define _CSIGN 1 +#define _ILONG 0 +#define _MBMAX 8 +#define NAN 2 +#define INF 1 +#define FINITE -1 +#define _DFRAC ((1 << _DOFF) - 1) +#define _DMASK (0x7fff & ~_DFRAC) +#define _DMAX ((1 << (15 - _DOFF)) - 1) +#define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1)) +#define _DSIGN 0x8000 +#define _D1 1 // big-endian order +#define _D2 2 +#define _D3 3 + +#define ALIGN(s, align) (((u32)(s) + ((align)-1)) & ~((align)-1)) + +void _Ldtob(_Pft* px, char_x code) { + char_x buff[BUFF_LEN]; + char_x *p; + f64 ldval; + s16 err; + s16 nsig; + s16 xexp; + + p = buff; + ldval = px->v.ld; + + if (px->prec < 0) { + px->prec = 6; + } else if (px->prec == 0 && (code == 'g' || code == 'G')) { + px->prec = 1; + } + + err = _Ldunscale(&xexp, px); + if (err > 0) { + memcpy(px->s, err == 2 ? "NaN" : "Inf", px->n1 = 3); + return; + } else if (err == 0) { + nsig = 0; + xexp = 0; + } else { + int i; + int n; + + if (ldval < 0) { + ldval = -ldval; + } + + // what + if ((xexp = xexp * 30103 / 100000 - 4) < 0) { + n = ALIGN(-xexp, 4), xexp = -n; + + for (i = 0; n > 0; n >>= 1, i++) { + if (n & 1) { + ldval *= pows[i]; + } + } + } else if (xexp > 0) { + f64 factor = 1; + + xexp &= ~3; + + for (n = xexp, i = 0; n > 0; n >>= 1, i++) { + if (n & 1) { + factor *= pows[i]; + } + } + + ldval /= factor; + } + { + int gen = px->prec + ((code == 'f') ? 10 + xexp : 6); + + if (gen > 0x13) { + gen = 0x13; + } + + for (*p++ = '0'; gen > 0 && 0 < ldval; p += 8) { + int j; + int lo = ldval; + + if ((gen -= 8) > 0) { + ldval = (ldval - lo) * 1e8; + } + + for (p += 8, j = 8; lo > 0 && --j >= 0;) { + ldiv_t qr = ldiv(lo, 10); + *--p = qr.rem + '0', lo = qr.quot; + } + + while (--j >= 0) { + *--p = '0'; + } + } + + gen = p - &buff[1]; + + for (p = &buff[1], xexp += 7; *p == '0'; p++) { + --gen, --xexp; + } + + nsig = px->prec + ((code == 'f') ? xexp + 1 : ((code == 'e' || code == 'E') ? 1 : 0)); + + if (gen < nsig) { + nsig = gen; + } + + if (nsig > 0) { + char_x drop = nsig < gen && '5' <= p[nsig] ? '9' : '0'; + int n; + + for (n = nsig; p[--n] == drop;) { + --nsig; + } + + if (drop == '9') { + ++p[n]; + } + + if (n < 0) { + --p, ++nsig, ++xexp; + } + } + } + } + + _Genld(px, code, (u8*) p, nsig, xexp); +} + +s16 _Ldunscale(s16* pex, _Pft* px) { + u16* ps = (u16*) px; + s16 xchar = (ps[_D0] & _DMASK) >> _DOFF; + + + if (xchar == _DMAX) { + *pex = 0; + + return (ps[_D0] & _DFRAC) || ps[_D1] || ps[_D2] || ps[_D3] ? 2 : 1; + } else if (xchar > 0) { + ps[_D0] = (ps[_D0] & ~_DMASK) | 0x3FF0; + *pex = xchar - 0x3FE; + return -1; + } else if (xchar < 0) { + return 2; + } else { + *pex = 0; + return 0; + } +} + +void _Genld(_Pft* px, char_x code, u8* p, s16 nsig, s16 xexp) { + const unsigned char point = '.'; + + if (nsig <= 0) { + nsig = 1, p = (u8*) "0"; // memes + } + + if (code == 'f' || ((code == 'g' || code == 'G') && (xexp >= -4 && xexp < px->prec))) { + xexp += 1; + if (code != 'f') { + if (((px->flags & 8) == 0) && nsig < px->prec) { + px->prec = nsig; + } + + px->prec -= xexp; + if (px->prec < 0) { + px->prec = 0; + } + } + + if (xexp <= 0) { + px->s[px->n1++] = '0'; + + if (px->prec > 0 || (px->flags & 8)) { + px->s[px->n1++] = point; + } + + if (px->prec < -xexp) { + xexp = -px->prec; + } + + px->nz1 = -xexp; + px->prec += xexp; + + if (px->prec < nsig) { + nsig = px->prec; + } + + memcpy(&px->s[px->n1], p, px->n2 = nsig); // , memes (this one is insane) + px->nz2 = px->prec - nsig; + } else if (nsig < xexp) { + memcpy(&px->s[px->n1], p, nsig); + px->n1 += nsig; + px->nz1 = xexp - nsig; + if (px->prec > 0 || (px->flags & 8)) { + px->s[px->n1] = point; + px->n2 += 1; + } + + px->nz2 = px->prec; + } else { + memcpy(&px->s[px->n1], p, xexp); + px->n1 += xexp; + nsig -= xexp; + + if (px->prec > 0 || (px->flags & 8)) { + px->s[px->n1++] = point; + } + + if (px->prec < nsig) { + nsig = px->prec; + } + + memcpy(&px->s[px->n1], &p[xexp], nsig); + px->n1 += nsig; + px->nz1 = px->prec - nsig; + } + } else { + if (code == 'g' || code == 'G') { + if (nsig < px->prec) { + px->prec = nsig; + } + + if (--px->prec < 0) { + px->prec = 0; + } + + code = (code == 'g') ? 'e' : 'E'; + } + + px->s[px->n1++] = *p++; + + if (px->prec > 0 || (px->flags & 8)) { + px->s[px->n1++] = point; + } + + if (px->prec > 0) { + if (px->prec < --nsig) { + nsig = px->prec; + } + + memcpy(&px->s[px->n1], p, nsig); + px->n1 += nsig; + px->nz1 = px->prec - nsig; + } + + p = &px->s[px->n1]; + *p++ = code; + + if (xexp >= 0) { + *p++ = '+'; + } else { + *p++ = '-'; + xexp = -xexp; + } + + if (xexp >= 100) { + if (xexp >= 1000) { + *p++ = (xexp / 1000) + '0', xexp %= 1000; // , memes + } + *p++ = (xexp / 100) + '0', xexp %= 100; // , memes + } + *p++ = (xexp / 10) + '0', xexp %= 10; // , memes + + *p++ = xexp + '0'; + px->n2 = (size_t)p - ((size_t)px->s + px->n1); + } + + if ((px->flags & 0x14) == 0x10) { + s32 n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2; + + if (n < px->width) { + px->nz0 = px->width - n; + } + } +} diff --git a/lib/ultra/libc/xlitob.c b/lib/ultra/libc/xlitob.c new file mode 100644 index 00000000..703a176c --- /dev/null +++ b/lib/ultra/libc/xlitob.c @@ -0,0 +1,59 @@ +#include +#include +#include "xstdio.h" + +#define BUFF_LEN 0x18 + +static char_x ldigs[] = "0123456789abcdef"; +static char_x udigs[] = "0123456789ABCDEF"; + +void _Litob(_Pft *args, char_x type) { + char buff[BUFF_LEN]; + const char_x *digs; + s32 base; + s32 i; + unsigned long long ullval; + + if (type == 'X') { + digs = udigs; + } else { + digs = ldigs; + } + + base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); + i = BUFF_LEN; + ullval = args->v.ll; + + if ((type == 'd' || type == 'i') && args->v.ll < 0) { + ullval = -ullval; + } + + if (ullval != 0 || args->prec != 0) { + buff[--i] = digs[ullval % base]; + } + + args->v.ll = ullval / base; + + while (args->v.ll > 0 && i > 0) { + lldiv_t qr = lldiv(args->v.ll, base); + + args->v.ll = qr.quot; + buff[--i] = digs[qr.rem]; + } + + args->n1 = BUFF_LEN - i; + + memcpy(args->s, buff + i, args->n1); + + if (args->n1 < args->prec) { + args->nz0 = args->prec - args->n1; + } + + if (args->prec < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { + i = args->width - args->n0 - args->nz0 - args->n1; + + if (i > 0) { + args->nz0 += i; + } + } +} diff --git a/lib/ultra/libc/xprintf.c b/lib/ultra/libc/xprintf.c new file mode 100644 index 00000000..96c6d6ae --- /dev/null +++ b/lib/ultra/libc/xprintf.c @@ -0,0 +1,247 @@ +#include +#include +#include "xstdio.h" + +#define isdigit(x) ((x >= '0' && x <= '9')) +#define LDSIGN(x) (((unsigned short *)&(x))[0] & 0x8000) + +#define ATOI(dst, src) \ + for (dst = 0; isdigit(*src); ++src) \ + { \ + if (dst < 999) \ + dst = dst * 10 + *src - '0'; \ + } + +#define PUT(s, n) \ + if (0 < (n)) \ + { \ + if ((arg = (*prout)(arg, (char*) s, n)) != NULL) \ + x.nchar += (n); \ + else \ + return x.nchar; \ + } + +#define MAX_PAD ((sizeof(spaces) - 1)) +#define PAD(s, n) \ + if (0 < (n)) \ + { \ + int i, j = (n); \ + for (; 0 < j; j -= i) \ + { \ + i = MAX_PAD < (unsigned int)j ? (int)MAX_PAD : j; \ + PUT(s, i); \ + } \ + } + +static char spaces[] = " "; +static char zeroes[] = "00000000000000000000000000000000"; + +static void _Putfld(_Pft *pf, va_list *pap, char_x code, char_x *ac); + +int _Printf(outfun prout, char *arg, const char *fmt, va_list args) { + _Pft x; + const char_x *s; + char_x c; + const char *t; + static const char fchar[] = {' ', '+', '-', '#', '0', '\0'}; + static const int fbit[] = {FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0}; + char_x ac[32]; + + x.nchar = 0; + + while (1) { + s = (char_x*) fmt; + +#if LIBULTRA_VERSION >= OS_VER_H + // new version: don't point fmt_ptr beyond NUL character + while ((c = *s) != 0 && c != '%') { + s++; + } +#else + while ((c = *s++) > 0) { + if (c == '%') { + s--; + break; + } + } +#endif + + PUT(fmt, s - (char_x*) fmt); + + if (c == 0) { + return x.nchar; + } + + fmt = (char*) ++s; + + for (x.flags = 0; (t = strchr(fchar, *s)) != NULL; s++) { + x.flags |= fbit[t - fchar]; + } + + if (*s == '*') { + x.width = va_arg(args, int); + + if (x.width < 0) { + x.width = -x.width; + x.flags |= FLAGS_MINUS; + } + s++; + } else { + ATOI(x.width, s); + } + + if (*s != '.') { + x.prec = -1; + } else if (*++s == '*') { + x.prec = va_arg(args, int); + ++s; + } else { + ATOI(x.prec, s); + } + + x.qual = strchr("hlL", *s) ? *s++ : '\0'; + + if (x.qual == 'l' && *s == 'l') { + x.qual = 'L'; + ++s; + } + + _Putfld(&x, &args, *s, ac); + x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + x.n2 + x.nz2; + + if (!(x.flags & FLAGS_MINUS)) { + PAD(spaces, x.width); + } + + PUT(ac, x.n0); + PAD(zeroes, x.nz0); + PUT(x.s, x.n1); + PAD(zeroes, x.nz1); + PUT(x.s + x.n1, x.n2); + PAD(zeroes, x.nz2); + + if (x.flags & FLAGS_MINUS) { + PAD(spaces, x.width); + } + + fmt = (char*) s + 1; + } + return 0; +} + +static void _Putfld(_Pft *x, va_list *args, char_x type, char_x *buff) { + x->n0 = x->nz0 = x->n1 = x->nz1 = x->n2 = + x->nz2 = 0; + + switch (type) { + case 'c': + buff[x->n0++] = va_arg(*args, int); + break; + case 'd': + case 'i': + if (x->qual == 'l') { + x->v.ll = va_arg(*args, int); + } else if (x->qual == 'L') { + x->v.ll = va_arg(*args, s64); + } else { + x->v.ll = va_arg(*args, int); + } + + if (x->qual == 'h') { + x->v.ll = (s16)x->v.ll; + } + + if (x->v.ll < 0) { + buff[x->n0++] = '-'; + } else if (x->flags & FLAGS_PLUS) { + buff[x->n0++] = '+'; + } else if (x->flags & FLAGS_SPACE) { + buff[x->n0++] = ' '; + } + + x->s = (u8*) &buff[x->n0]; + + _Litob(x, type); + break; + case 'x': + case 'X': + case 'u': + case 'o': + if (x->qual == 'l') { + x->v.ll = va_arg(*args, int); + } else if (x->qual == 'L') { + x->v.ll = va_arg(*args, s64); + } else { + x->v.ll = va_arg(*args, int); + } + + if (x->qual == 'h') { + x->v.ll = (u16)x->v.ll; + } else if (x->qual == 0) { + x->v.ll = (unsigned int)x->v.ll; + } + + if (x->flags & FLAGS_HASH) { + buff[x->n0++] = '0'; + + if (type == 'x' || type == 'X') { + buff[x->n0++] = type; + } + } + + x->s = (u8*) &buff[x->n0]; + _Litob(x, type); + break; + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + //... okay? + x->v.ld = x->qual == 'L' ? va_arg(*args, f64) : va_arg(*args, f64); + + if (LDSIGN(x->v.ld)) + buff[x->n0++] = '-'; + else if (x->flags & FLAGS_PLUS) + buff[x->n0++] = '+'; + else if (x->flags & FLAGS_SPACE) + buff[x->n0++] = ' '; + + x->s = (u8*) &buff[x->n0]; + _Ldtob(x, type); + break; + + case 'n': + if (x->qual == 'h') { + *(va_arg(*args, u16 *)) = x->nchar; + } else if (x->qual == 'l') { + *va_arg(*args, unsigned int *) = x->nchar; + } else if (x->qual == 'L') { + *va_arg(*args, u64 *) = x->nchar; + } else { + *va_arg(*args, unsigned int *) = x->nchar; + } + + break; + case 'p': + x->v.ll = (long)va_arg(*args, void *); + x->s = (u8*) &buff[x->n0]; + _Litob(x, 'x'); + break; + case 's': + x->s = (u8 *) va_arg(*args, char_x *); + x->n1 = strlen((char *)x->s); + + if (x->prec >= 0 && x->n1 > x->prec) { + x->n1 = x->prec; + } + + break; + case '%': + buff[x->n0++] = '%'; + break; + default: + buff[x->n0++] = type; + break; + } +} diff --git a/lib/ultra/libc/xstdio.h b/lib/ultra/libc/xstdio.h new file mode 100644 index 00000000..9dfd4917 --- /dev/null +++ b/lib/ultra/libc/xstdio.h @@ -0,0 +1,43 @@ +#ifndef _XSTDIO_H +#define _XSTDIO_H +#include "PR/os_version.h" +#include +#include + +#if LIBULTRA_VERSION >= OS_VER_I +typedef char char_x; +#else +typedef unsigned char char_x; +#endif + +typedef struct { + /* 0x0 */ union { + /* 0x0 */ long long ll; + /* 0x0 */ double ld; + } v; + /* 0x8 */ unsigned char* s; + /* 0xC */ int n0; + /* 0x10 */ int nz0; + /* 0x14 */ int n1; + /* 0x18 */ int nz1; + /* 0x1C */ int n2; + /* 0x20 */ int nz2; + /* 0x24 */ int prec; + /* 0x28 */ int width; + /* 0x2C */ size_t nchar; + /* 0x30 */ unsigned int flags; + /* 0x34 */ char_x qual; +} _Pft; + +#define FLAGS_SPACE 1 +#define FLAGS_PLUS 2 +#define FLAGS_MINUS 4 +#define FLAGS_HASH 8 +#define FLAGS_ZERO 16 +typedef char *outfun(char*,const char*,size_t); + +int _Printf(outfun prout, char *arg, const char *fmt, va_list args); +void _Litob(_Pft *args, char_x type); +void _Ldtob(_Pft* args, char_x type); + +#endif diff --git a/lib/ultra/mgu/guasm.h b/lib/ultra/mgu/guasm.h new file mode 100644 index 00000000..4e1d6786 --- /dev/null +++ b/lib/ultra/mgu/guasm.h @@ -0,0 +1,37 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO CO,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO CO,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO CO,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/06/16 09:15:38 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#include "PR/os_version.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +#define HALF_SIZE_MTX 32 +#define SIZE_OF_MTX 64 /* sizeof( Mtx ) */ +#define FLOAT_0x10000 6.5536e+04 /* (float)0x00010000) */ + +/* + * FTOFIX32 (float to fix32) + * a: input + * t: output + * ft0 : (float)0x00010000 + * ft1, ft2, ft3, t0 : work reg + */ +#define FTOFIX32(a, t) \ + mtc1 a, ft1 ; \ + mul.s ft2, ft1, ft0 ; \ + trunc.w.s ft3, ft2, t0 ; \ + mfc1 t, ft3 ; diff --git a/lib/ultra/mgu/mtxf2l.s b/lib/ultra/mgu/mtxf2l.s new file mode 100644 index 00000000..1aba6cb7 --- /dev/null +++ b/lib/ultra/mgu/mtxf2l.s @@ -0,0 +1,80 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO CO,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO CO,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO CO,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/06/16 09:15:38 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#include "guasm.h" + +#if LIBULTRA_VERSION >= OS_VER_K && defined(TARGET_N64) + +/* + * void guMtxF2L(float mf[4][4], Mtx *m) + * + * Input + * float mf[4][4] + * Output + * Mtx *m + */ + +#define MASK_LOW 0x0000FFFF +#define MASK_HIGH 0xFFFF0000 + +#define ptr_fl a0 /* argument */ +#define ptr_mtx a1 /* argument */ +#define end_mtx t8 +#define mask_hi t9 +#define magni fv0 + + .text + .align 5 +LEAF( guMtxF2L ) + .set reorder + + li.s magni, FLOAT_0x10000 + li mask_hi, MASK_HIGH + addu end_mtx, ptr_mtx, HALF_SIZE_MTX +label_loop: + l.s ft0, 0(ptr_fl) /* FTOFIX32( ) */ + mul.s ft1, ft0, magni + trunc.w.s ft2, ft1 + + l.s ft3, 4(ptr_fl) /* FTOFIX32( ) */ + mul.s ft4, ft3, magni + trunc.w.s ft5, ft4 + + mfc1 t0, ft2 /* t0 <- FIXED */ + mfc1 t1, ft5 /* t1 <- FIXED */ + + and t2, t0, mask_hi /* integral part */ + srl t3, t1, 16 + or ta0, t2, t3 + sw ta0, 0(ptr_mtx) + + sll ta1, t0, 16 /* decimal part */ + and ta2, t1, MASK_LOW + or ta3, ta1, ta2 + sw ta3, HALF_SIZE_MTX(ptr_mtx) + + addu ptr_mtx, ptr_mtx, 4 + addu ptr_fl, ptr_fl, 8 + + bne ptr_mtx, end_mtx, label_loop +/* loop-end */ + + j ra + END( guMtxF2L ) + +/* End of file */ +#endif diff --git a/lib/ultra/mgu/mtxidentf.s b/lib/ultra/mgu/mtxidentf.s new file mode 100644 index 00000000..7e740f17 --- /dev/null +++ b/lib/ultra/mgu/mtxidentf.s @@ -0,0 +1,64 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO CO,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO CO,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO CO,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/06/16 09:15:38 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#include "guasm.h" + +#if LIBULTRA_VERSION >= OS_VER_K && defined(TARGET_N64) + +/* + * guMtxIdentF( float matrix[4][4] ) + * substitute unit matrix for floating point matrix + * correspond only when alignment is four byte boundary + * Input + * a0 = matrix + * Output + * *matrix unti matix + */ + .text + .align 5 +LEAF( guMtxIdentF ) + .set reorder + + li t0, 0x3f800000 /* t0 = 1.0 */ + + sw t0, 0(a0) + sw zero, 4(a0) /* line 1 */ + sw zero, 8(a0) + sw zero, 12(a0) + + sw zero, 16(a0) /* line 2 */ + sw t0, 20(a0) + sw zero, 24(a0) + sw zero, 28(a0) + + sw zero, 32(a0) /* line 3 */ + sw zero, 36(a0) + sw t0, 40(a0) + sw zero, 44(a0) + + sw zero, 48(a0) /* line 4 */ + sw zero, 52(a0) + sw zero, 56(a0) + sw t0, 60(a0) + + j ra + + END( guMtxIdentF ) + +/* End of file */ + +#endif diff --git a/lib/ultra/mgu/normalize.s b/lib/ultra/mgu/normalize.s new file mode 100644 index 00000000..96c6f806 --- /dev/null +++ b/lib/ultra/mgu/normalize.s @@ -0,0 +1,60 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO CO,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO CO,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO CO,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/06/16 09:15:39 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#include "guasm.h" + +#if LIBULTRA_VERSION >= OS_VER_K && defined(TARGET_N64) + +/* + * void guNormalize(float *x, float *y, float *z) + */ + .text + .align 5 +LEAF( guNormalize ) + .set noreorder + + l.s ft0, 0(a0) /* ft0 = x */ + l.s ft1, 0(a1) /* ft1 = y */ + l.s ft2, 0(a2) /* ft2 = z */ + + mul.s ft3, ft0, ft0 /* ft3 = x*x */ + lui t0, 0x3f80 /* t0 = 1.0f */ + mul.s ft4, ft1, ft1 /* ft4 = y*y */ + add.s ft5, ft3, ft4 + mul.s ft4, ft2, ft2 /* ft4 = z*z */ + + add.s ft3, ft4, ft5 /* ft3 = x*x + y*y + z*z */ + mtc1 t0, ft5 + sqrt.s ft4, ft3 /* ft4 = sqrt(x*x + y*y + z*z) */ + + div.s ft3, ft5, ft4 /* ft3 = 1/sqrt(x*x + y*y + z*z) */ + + mul.s ft4, ft0, ft3 /* ft4 = x * 1/sqrt(x*x + y*y + z*z) */ + nop + mul.s ft5, ft1, ft3 /* ft5 = y * 1/sqrt(x*x + y*y + z*z) */ + nop + mul.s ft0, ft2, ft3 /* ft0 = z * 1/sqrt(x*x + y*y + z*z) */ + + s.s ft4, 0(a0) /* x = ft4 */ + s.s ft5, 0(a1) /* y = ft5 */ + j ra + s.s ft0, 0(a2) /* z = ft0 */ /* Use delayed slot */ + + END( guNormalize ) +/* end of file */ + +#endif diff --git a/lib/ultra/mgu/scale.s b/lib/ultra/mgu/scale.s new file mode 100644 index 00000000..8af24003 --- /dev/null +++ b/lib/ultra/mgu/scale.s @@ -0,0 +1,74 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO CO,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO CO,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO CO,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/06/16 09:15:40 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#include "guasm.h" + +#if LIBULTRA_VERSION >= OS_VER_K && defined(TARGET_N64) + +/* + void guScale(Mtx *m, float x, float y, float z) + m: a0 + x: a1 + y: a2 + z a3 + */ + + .text + .align 5 +LEAF( guScale ) + .set reorder + + li.s ft0, FLOAT_0x10000 /* (float)0x00010000 */ + + FTOFIX32(a1, t1) /* t1 = FTOFIX32(x) */ + srl t2, t1, 16 + sll t0, t2, 16 + sw t0, 0(a0) /* t0 = x integral part */ + sll t2, t1, 16 + sw t2, 32(a0) /* t2 = x decimal part */ + + FTOFIX32(a2, t1) /* t1 = FTOFIX32(y) */ + srl t0, t1, 16 + sw t0, 8(a0) /* t0 = y integral part */ + andi t2, t1, 0xffff + sw t2, 40(a0) /* t2 = y decimal part */ + + FTOFIX32(a3, t1) /* t1 = FTOFIX32(z) */ + srl t2, t1, 16 + sll t0, t2, 16 + sw t0, 20(a0) /* t0 = z integral part */ + sll t2, t1, 16 + sw t2, 52(a0) /* t2 = z decimal part */ + + li t0, 1 /* t0 = 1.0 integral part */ + sw t0, 28(a0) + + sw zero, 4(a0) + sw zero, 12(a0) + sw zero, 16(a0) + sw zero, 24(a0) + sw zero, 36(a0) + sw zero, 44(a0) + sw zero, 48(a0) + sw zero, 56(a0) + sw zero, 60(a0) + j ra + + END( guScale ) +/* end of file */ + +#endif diff --git a/lib/ultra/mgu/translate.s b/lib/ultra/mgu/translate.s new file mode 100644 index 00000000..775a41bd --- /dev/null +++ b/lib/ultra/mgu/translate.s @@ -0,0 +1,93 @@ +/************************************************************************ + Copyright (C) 1998,1999 NINTENDO CO,Ltd, + Copyright (C) 1998,1999 MONEGI CORPORATION, + All Rights Reserved +This program is a trade secret of NINTENDO CO,Ltd and MONEGI Corp. +and it is not to be reproduced, published, disclosed to others, copied, +adapted, distributed, or displayed without the prior authorization of +NINTENDO CO,Ltd. and MONEGI Corp. Licensee agrees to attach or embed +this Notice on all copies of the program, including partial copies or +modified versions thereof. +*************************************************************************/ +/************************************************************************ + $Date: 1999/06/16 09:15:40 $ + $Revision: 1.1 $ + $Author: doseki $ +************************************************************************/ + +#include "guasm.h" + +#if LIBULTRA_VERSION >= OS_VER_K && defined(TARGET_N64) + +/* + void guTranslate(Mtx *m, float x, float y, float z) + m: a0 + x: a1 + y: a2 + z a3 + */ + + .text + .align 5 +LEAF( guTranslate ) + .set reorder + + li.s ft0, FLOAT_0x10000 /* (float)0x00010000 */ + + FTOFIX32(a1, t1) /* t1 = FTOFIX32(x) */ + + FTOFIX32(a2, t3) /* t3 = FTOFIX32(y) */ + + /* Save t1 and t3 values until fraction process is finished! */ + + srl t2, t1, 16 /* x integeral part for t0 interger */ + sll t0, t2, 16 + srl t2, t3, 16 /* y integral part for t2 fraction */ + or t0, t0, t2 /* Compose in t0 */ + sw t0, 24(a0) + + sll t0,t1,16 /* x fraction part for t0 interger */ + sll t2,t3,16 + srl t2,t2,16 /* y fraction part for t2 fraction */ + or t0,t0,t2 /* Compose in t0 */ + sw t0,24+32(a0) + + + FTOFIX32(a3, t1) /* t1 = FTOFIX32(z) */ + + srl t2,t1,16 + sll t0,t2,16 /* z integral part for t0 integer */ + addiu t0,t0,1 /* enter 0x0001 in t0 fraction */ + sw t0,28(a0) + + sll t2,t1,16 /* z fraction part for t2 integer */ + sw t2,28+32(a0) + + sw zero, 0(a0) + sw zero, 4(a0) + sw zero, 8(a0) + sw zero, 12(a0) + sw zero, 16(a0) + sw zero, 20(a0) + sw zero, 0+32(a0) + sw zero, 4+32(a0) + sw zero, 8+32(a0) + sw zero, 12+32(a0) + sw zero, 16+32(a0) + sw zero, 20+32(a0) + + lui t0,0x0001 + ori t0,0x0000 + sw t0,0(a0) + sw t0,20(a0) + + lui t0,0x0000 + ori t0,0x0001 + sw t0,8(a0) + + j ra + + END( guTranslate ) +/* end of file */ + +#endif diff --git a/lib/ultra/os/atomic.c b/lib/ultra/os/atomic.c new file mode 100644 index 00000000..10949024 --- /dev/null +++ b/lib/ultra/os/atomic.c @@ -0,0 +1,16 @@ +#include "PR/os_internal.h" + +s32 __osAtomicDec(u32 *p) { + s32 mask; + s32 result; + + mask = __osDisableInt(); + if (*p != 0) { + (*p)--; + result = 1; + } else { + result = 0; + } + __osRestoreInt(mask); + return result; +} diff --git a/lib/ultra/os/createmesgqueue.c b/lib/ultra/os/createmesgqueue.c new file mode 100644 index 00000000..87d43753 --- /dev/null +++ b/lib/ultra/os/createmesgqueue.c @@ -0,0 +1,11 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osCreateMesgQueue(OSMesgQueue *mq, OSMesg *msg, s32 msgCount) { + mq->mtqueue = (OSThread *) &__osThreadTail.next; + mq->fullqueue = (OSThread *) &__osThreadTail.next; + mq->validCount = 0; + mq->first = 0; + mq->msgCount = msgCount; + mq->msg = msg; +} diff --git a/lib/ultra/os/createthread.c b/lib/ultra/os/createthread.c new file mode 100644 index 00000000..00add987 --- /dev/null +++ b/lib/ultra/os/createthread.c @@ -0,0 +1,30 @@ +#include "PR/os_internal.h" +#include "PR/R4300.h" +#include "osint.h" + +void osCreateThread(OSThread *t, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri p) { + register u32 saveMask; + OSIntMask mask; + + t->id = id; + t->priority = p; + t->next = NULL; + t->queue = NULL; + t->context.pc = (u32) entry; + t->context.a0 = (s64) (s32) arg; // Double cast gets rid of compiler warning + t->context.sp = (s64) (s32) sp - 16; + t->context.ra = (s64) (s32) __osCleanupThread; + mask = OS_IM_ALL; + t->context.sr = (mask & (SR_IMASK | SR_IE)) | SR_EXL; + t->context.rcp = (mask & RCP_IMASK) >> RCP_IMASKSHIFT; + t->context.fpcsr = (u32) (FPCSR_FS | FPCSR_EV); + t->fp = 0; + t->state = OS_STATE_STOPPED; + t->flags = 0; + + saveMask = __osDisableInt(); + t->tlnext = __osActiveQueue; + + __osActiveQueue = t; + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/os/destroythread.c b/lib/ultra/os/destroythread.c new file mode 100644 index 00000000..255242d4 --- /dev/null +++ b/lib/ultra/os/destroythread.c @@ -0,0 +1,48 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osDestroyThread(OSThread *t) { + register s32 saveMask; + register OSThread *pred; + register OSThread *succ; + + saveMask = __osDisableInt(); + + if (t == NULL) { + t = __osRunningThread; + } else if (t->state != OS_STATE_STOPPED) { + __osDequeueThread(t->queue, t); + } + + if (__osActiveQueue == t) { + __osActiveQueue = __osActiveQueue->tlnext; + } else { + pred = __osActiveQueue; +#if LIBULTRA_VERSION >= OS_VER_J + while (pred->priority != -1) { + succ = pred->tlnext; + if (succ == t) { + pred->tlnext = t->tlnext; + break; + } + pred = succ; + } +#else + succ = pred->tlnext; + while (succ != NULL) { + if (succ == t) { + pred->tlnext = t->tlnext; + break; + } + pred = succ; + succ = pred->tlnext; + } +#endif + } + + if (t == __osRunningThread) { + __osDispatchThread(); + } + + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/os/exceptasm.h b/lib/ultra/os/exceptasm.h new file mode 100644 index 00000000..c060bed9 --- /dev/null +++ b/lib/ultra/os/exceptasm.h @@ -0,0 +1,27 @@ +#ifndef _EXCEPTASM_H +#define _EXCEPTASM_H + +#define MESG(type) (type << 3) + +#define MQ_MTQUEUE 0 +#define MQ_FULLQUEUE 4 +#define MQ_VALIDCOUNT 8 +#define MQ_FIRST 12 +#define MQ_MSGCOUNT 16 +#define MQ_MSG 20 + +#define OS_EVENTSTATE_MESSAGE_QUEUE 0 +#define OS_EVENTSTATE_MESSAGE 4 + +/* __osHwInt struct member offsets */ +#define HWINTR_CALLBACK 0x00 +#define HWINTR_SP 0x04 + +/* __osHwInt struct size */ +#if LIBULTRA_VERSION >= OS_VER_J +#define HWINTR_SIZE 0x8 +#else +#define HWINTR_SIZE 0x4 +#endif + +#endif diff --git a/lib/ultra/os/exceptasm.s b/lib/ultra/os/exceptasm.s new file mode 100644 index 00000000..78074f22 --- /dev/null +++ b/lib/ultra/os/exceptasm.s @@ -0,0 +1,943 @@ +/* Enforce registers to be 64 bits on modern GCC */ +#if !defined(__sgi) && !defined(EGCS_GCC) +.set gp=64 +#endif + +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" +#include "PR/os.h" +#include "PR/rcp.h" +#include "PR/rdb.h" +#include "exceptasm.h" +#include "threadasm.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +#define KMC_CODE_ENTRY 0xBFF00014 +#define KMC_WPORT 0xBFF08000 +#define KMC_STAT 0xBFF08004 + +#ifdef BBPLAYER +#define XOR_VALUE 0xFFFFFFFF +#else +#define XOR_VALUE ~0 +#endif + +#if LIBULTRA_VERSION >= OS_VER_J +#define INT_TABLE(arg1, arg2) .word arg1, arg2 +#else +#define INT_TABLE(arg1, arg2) .word arg1 +#endif + +#if LIBULTRA_VERSION <= OS_VER_D +#define IP_H(arg) panic +#else +#define IP_H(arg) arg +#endif + +.rdata + +#define REDISPATCH 0x00 +#define SW1 0x04 +#define SW2 0x08 +#define RCP 0x0c +#define CART 0x10 +#define PRENMI 0x14 +#define IP6_HDLR 0x18 +#define IP7_HDLR 0x1c +#define COUNTER 0x20 + +__osIntOffTable: + .byte REDISPATCH + .byte PRENMI + .byte IP6_HDLR + .byte IP6_HDLR + .byte IP7_HDLR + .byte IP7_HDLR + .byte IP7_HDLR + .byte IP7_HDLR + .byte COUNTER + .byte COUNTER + .byte COUNTER + .byte COUNTER + .byte COUNTER + .byte COUNTER + .byte COUNTER + .byte COUNTER + .byte REDISPATCH + .byte SW1 + .byte SW2 + .byte SW2 + .byte RCP + .byte RCP + .byte RCP + .byte RCP + .byte CART + .byte CART + .byte CART + .byte CART + .byte CART + .byte CART + .byte CART + .byte CART + +__osIntTable: + .word redispatch, sw1, sw2, rcp, cart, prenmi, IP_H(IP6_Hdlr), IP_H(IP7_Hdlr), counter + +.data + +EXPORT(__osHwIntTable) + INT_TABLE(0, 0) + INT_TABLE(0, 0) + INT_TABLE(0, 0) + INT_TABLE(0, 0) + INT_TABLE(0, 0) + +#if LIBULTRA_VERSION > OS_VER_D +EXPORT(__osPiIntTable) + INT_TABLE(0, 0) +#endif + +#if LIBULTRA_VERSION <= OS_VER_D || !defined(_FINALROM) +__os_Kdebug_Pkt: + .word 0 + +__osRdb_Mesg: + .word 0 +#endif + +.text + +LEAF(__osExceptionPreamble) + la k0, __osException + jr k0 +END(__osExceptionPreamble) + +LEAF(__osException) + la k0, __osThreadSave + /* save AT */ +.set noat + sd $1, THREAD_GP1(k0) +.set at + /* save sr */ +STAY2(mfc0 k1, C0_SR) + sw k1, THREAD_SR(k0) + /* clear interrupts */ + and k1, k1, -4 +STAY2(mtc0 k1, C0_SR) + /* save other regs */ + sd $8, THREAD_GP8(k0) + sd $9, THREAD_GP9(k0) + sd $10, THREAD_GP10(k0) + /* say fp has not been used */ + sw zero, THREAD_FP(k0) + /* this instruction is useless, leftover because of bad placement of an ifdef for the debug version */ +STAY2(mfc0 t0, C0_CAUSE) +#if LIBULTRA_VERSION <= OS_VER_D || !defined(_FINALROM) + andi t1, t0, 0x7c + li t2, 0 + bne t1, t2, savecontext + and t1, k1, t0 + andi t2, t1, 0x4000 + beqz t2, rdb_message + li t1, 1 + sw t1, __os_Kdebug_Pkt + b gp_threads +rdb_message: + andi t2, t1, 0x2000 + beqz t2, savecontext + li t1, 1 + sw t1, __osRdb_Mesg + b gp_threads +savecontext: + sw zero, __os_Kdebug_Pkt + sw zero, __osRdb_Mesg +#else +savecontext: +#endif + move t0, k0 + lw k0, __osRunningThread + ld t1, THREAD_GP1(t0) + sd t1, THREAD_GP1(k0) + ld t1, THREAD_SR(t0) + sd t1, THREAD_SR(k0) + ld t1, THREAD_GP8(t0) + sd t1, THREAD_GP8(k0) + ld t1, THREAD_GP9(t0) + sd t1, THREAD_GP9(k0) + ld t1, THREAD_GP10(t0) + sd t1, THREAD_GP10(k0) +gp_threads: /* Only referenced on 2.0D but required for instruction ordering to match */ + sd $2, THREAD_GP2(k0) + sd $3, THREAD_GP3(k0) + sd $4, THREAD_GP4(k0) + sd $5, THREAD_GP5(k0) + sd $6, THREAD_GP6(k0) + sd $7, THREAD_GP7(k0) + sd $11, THREAD_GP11(k0) + sd $12, THREAD_GP12(k0) + sd $13, THREAD_GP13(k0) + sd $14, THREAD_GP14(k0) + sd $15, THREAD_GP15(k0) + sd $16, THREAD_GP16(k0) + sd $17, THREAD_GP17(k0) + sd $18, THREAD_GP18(k0) + sd $19, THREAD_GP19(k0) + sd $20, THREAD_GP20(k0) + sd $21, THREAD_GP21(k0) + sd $22, THREAD_GP22(k0) + sd $23, THREAD_GP23(k0) + sd $24, THREAD_GP24(k0) + sd $25, THREAD_GP25(k0) + sd $28, THREAD_GP28(k0) + sd $29, THREAD_GP29(k0) + sd $30, THREAD_GP30(k0) + sd $31, THREAD_GP31(k0) + + mflo t0 + sd t0, THREAD_LO(k0) + mfhi t0 + sd t0, THREAD_HI(k0) +#if LIBULTRA_VERSION > OS_VER_D + lw k1, THREAD_SR(k0) + andi t1, k1, SR_IMASK + beqz t1, savercp + +/*if any interrupts are enabled*/ + la t0, __OSGlobalIntMask + lw t0, 0(t0) +#if LIBULTRA_VERSION <= OS_VER_F + xor t0, t0, XOR_VALUE /* not except not using not */ + andi t0, t0, SR_IMASK + or t1, t1, t0 + and k1, k1, ~SR_IMASK + or k1, k1, t1 + sw k1, THREAD_SR(k0) +#else + xor t2, t0, XOR_VALUE /* not except not using not */ + andi t2, t2, SR_IMASK + or ta0, t1, t2 + and t3, k1, ~SR_IMASK + or t3, t3, ta0 + sw t3, THREAD_SR(k0) + andi t0, t0, SR_IMASK + and t1, t1, t0 + and k1, k1, ~SR_IMASK + or k1, k1, t1 +#endif +#endif +savercp: + +#if LIBULTRA_VERSION > OS_VER_D + lw t1, PHYS_TO_K1(MI_INTR_MASK_REG) + beqz t1, endrcp + + la t0, __OSGlobalIntMask + lw t0, 0(t0) + + srl t0, t0, 0x10 + xor t0, t0, XOR_VALUE + andi t0, t0, 0x3f + lw ta0, THREAD_RCP(k0) + and t0, t0, ta0 + or t1, t1, t0 +endrcp: + sw t1, THREAD_RCP(k0) +#endif +STAY2(mfc0 t0, C0_EPC) + sw t0, THREAD_PC(k0) + lw t0, THREAD_FP(k0) + beqz t0, 1f +STAY2(cfc1 t0, fcr31) + NOP + sw t0, THREAD_FPCSR(k0) + sdc1 $f0, THREAD_FP0(k0) + sdc1 $f2, THREAD_FP2(k0) + sdc1 $f4, THREAD_FP4(k0) + sdc1 $f6, THREAD_FP6(k0) + sdc1 $f8, THREAD_FP8(k0) + sdc1 $f10, THREAD_FP10(k0) + sdc1 $f12, THREAD_FP12(k0) + sdc1 $f14, THREAD_FP14(k0) + sdc1 $f16, THREAD_FP16(k0) + sdc1 $f18, THREAD_FP18(k0) + sdc1 $f20, THREAD_FP20(k0) + sdc1 $f22, THREAD_FP22(k0) + sdc1 $f24, THREAD_FP24(k0) + sdc1 $f26, THREAD_FP26(k0) + sdc1 $f28, THREAD_FP28(k0) + sdc1 $f30, THREAD_FP30(k0) +1: +STAY2(mfc0 t0, C0_CAUSE) + sw t0, THREAD_CAUSE(k0) +#if LIBULTRA_VERSION <= OS_VER_D + lw t1, PHYS_TO_K1(MI_INTR_MASK_REG) + sw t1, THREAD_RCP(k0) +#endif +.set noreorder + li t1, OS_STATE_RUNNABLE + sh t1, THREAD_STATE(k0) +.set reorder +#if LIBULTRA_VERSION <= OS_VER_D || !defined(_FINALROM) + lw t1, __os_Kdebug_Pkt + beqz t1, no_kdebug + la t2, RDB_WRITE_INTR_REG + sw zero, (t2) + lw a0, K2BASE + jal kdebugserver + b __osDispatchThreadSave +no_kdebug: + lw t1, __osRdb_Mesg + beqz t1, no_rdb_mesg + la t2, RDB_READ_INTR_REG + sw zero, (t2) + lw t1, __osRdbSendMessage + beqz t1, rdb_write + li a0, 120 + jal send_mesg +rdb_write: + lw t1, __osRdbWriteOK + addi t1, t1, 1 + sw t1, __osRdbWriteOK + b __osDispatchThreadSave +no_rdb_mesg: +#endif + andi t1, t0, CAUSE_EXCMASK + li t2, EXC_BREAK + beq t1, t2, handle_break + + li t2, EXC_CPU + beq t1, t2, handle_CpU + + li t2, EXC_INT + bne t1, t2, panic + +handle_interrupt: + and s0, k1, t0 +next_interrupt: + andi t1, s0, SR_IMASK + srl t2, t1, 0xc + bnez t2, 1f + + srl t2, t1, SR_IMASKSHIFT + addi t2, t2, 16 +1: + + lbu t2, __osIntOffTable(t2) + + lw t2, __osIntTable(t2) + jr t2 +#if LIBULTRA_VERSION > OS_VER_D +IP6_Hdlr: + and s0, s0, ~CAUSE_IP6 + b next_interrupt + +IP7_Hdlr: + and s0, s0, ~CAUSE_IP7 + b next_interrupt +#endif +counter: +STAY2(mfc0 t1, C0_COMPARE) +STAY2(mtc0 t1, C0_COMPARE) + li a0, MESG(OS_EVENT_COUNTER) + jal send_mesg + and s0, s0, ~CAUSE_IP8 + b next_interrupt + +cart: +#if LIBULTRA_VERSION > OS_VER_D + and s0, s0, ~CAUSE_IP4 +#endif +#if LIBULTRA_VERSION >= OS_VER_J + la t1, __osHwIntTable + add t1, HWINTR_SIZE + lw t2, HWINTR_CALLBACK(t1) + + beqz t2, 1f + + lw sp, HWINTR_SP(t1) +#else + li t2, HWINTR_SIZE + lw t2, __osHwIntTable(t2) +#if LIBULTRA_VERSION >= OS_VER_F + la sp, leoDiskStack + li a0, MESG(OS_EVENT_CART) + + addiu sp, sp, OS_LEO_STACKSIZE-16 # Stack size minus initial frame +#endif + beqz t2, 1f +#endif + jalr t2 +#if LIBULTRA_VERSION >= OS_VER_H && LIBULTRA_VERSION < OS_VER_J + li a0, MESG(OS_EVENT_CART) +#endif +#if LIBULTRA_VERSION > OS_VER_D + beqz v0, 1f + b redispatch +#endif +1: +#ifndef BBPLAYER +#if LIBULTRA_VERSION <= OS_VER_D + li a0, MESG(OS_EVENT_CART) +#endif + jal send_mesg +#else + lw s1, PHYS_TO_K1(MI_38_REG) + +flash: + andi t1, s1, 0x40 + beqz t1, flashx + + andi s1, s1, 0x3f80 + li t1, 0 + sw t1, PHYS_TO_K1(PI_48_REG) + li a0, MESG(OS_EVENT_FLASH) + jal send_mesg +flashx: + +md: + andi t1, s1, 0x2000 + beqz t1, mdx + + andi s1, s1, 0x1fc0 + li t1, 0x2000 + sw t1, PHYS_TO_K1(MI_38_REG) + li a0, MESG(OS_EVENT_MD) + jal send_mesg +mdx: + +aes: + andi t1, s1, 0x80 + beqz t1, aesx + + andi s1, s1, 0x3f40 + li t1, 0x4000 + sw t1, PHYS_TO_K1(MI_3C_REG) + li a0, MESG(OS_EVENT_AES) + jal send_mesg +aesx: + +ide: + andi t1, s1, 0x100 + beqz t1, idex + + andi s1, s1, 0x3ec0 + li t1, 0x10000 + sw t1, PHYS_TO_K1(MI_3C_REG) + li a0, MESG(OS_EVENT_IDE) + jal send_mesg +idex: + +pi_err: + andi t1, s1, 0x200 + beqz t1, pi_errx + + andi s1, s1, 0x3dc0 + li t1, 0x40000 + sw t1, PHYS_TO_K1(MI_3C_REG) + li a0, MESG(OS_EVENT_PI_ERR) + jal send_mesg +pi_errx: + +usb0: + andi t1, s1,0x400 + beqz t1, usb0x + + andi s1, s1, 0x3bc0 + li t1, 0x100000 + sw t1, PHYS_TO_K1(MI_3C_REG) + li a0, MESG(OS_EVENT_USB0) + jal send_mesg +usb0x: + +usb1: + andi t1, s1, 0x800 + beqz t1, usb1x + + andi s1, s1, 0x37c0 + li t1, 0x400000 + sw t1, PHYS_TO_K1(MI_3C_REG) + li a0, MESG(OS_EVENT_USB1) + jal send_mesg +usb1x: + +#endif +#if LIBULTRA_VERSION <= OS_VER_D + and s0, s0, ~CAUSE_IP4 +#endif + b next_interrupt + +rcp: + lw s1, PHYS_TO_K1(MI_INTR_REG) +#if LIBULTRA_VERSION > OS_VER_D + la t0, __OSGlobalIntMask + lw t0, (t0) + srl t0, t0, 0x10 + and s1, s1, t0 +#else + andi s1, s1, 0x3f +#endif + andi t1, s1, MI_INTR_SP + beqz t1, vi + + andi s1, s1, 0x3e + lw ta0, PHYS_TO_K1(SP_STATUS_REG) +#if LIBULTRA_VERSION >= OS_VER_I + li t1, (SP_CLR_INTR | SP_CLR_SIG3) +#else + li t1, (SP_CLR_INTR) +#endif + sw t1, PHYS_TO_K1(SP_STATUS_REG) + andi ta0, ta0, 0x300 + beqz ta0, sp_other_break + + li a0, MESG(OS_EVENT_SP) + jal send_mesg + + beqz s1, NoMoreRcpInts + + b vi + +sp_other_break: + li a0, MESG(OS_EVENT_SP_BREAK) + jal send_mesg + + beqz s1, NoMoreRcpInts + +vi: + andi t1, s1, 0x8 + beqz t1, ai + + andi s1, s1, 0x37 + + sw zero, PHYS_TO_K1(VI_CURRENT_REG) + li a0, MESG(OS_EVENT_VI) + jal send_mesg + beqz s1, NoMoreRcpInts + +ai: + andi t1, s1, 0x4 + beqz t1, si + + andi s1, s1, 0x3b + + li t1, 1 + sw t1, PHYS_TO_K1(AI_STATUS_REG) + + li a0, MESG(OS_EVENT_AI) + jal send_mesg + beqz s1, NoMoreRcpInts + +si: + andi t1, s1, 0x2 + beqz t1, pi + + andi s1, s1, 0x3d + /* any write clears interrupts */ + sw zero, PHYS_TO_K1(SI_STATUS_REG) + li a0, MESG(OS_EVENT_SI) + jal send_mesg + beqz s1, NoMoreRcpInts + +pi: + andi t1, s1, 0x10 + beqz t1, dp + + andi s1, s1, 0x2f + + li t1, PI_STATUS_CLR_INTR + sw t1, PHYS_TO_K1(PI_STATUS_REG) +#if LIBULTRA_VERSION >= OS_VER_J + la t1, __osPiIntTable + lw t2, (t1) + beqz t2, 1f + + lw sp, 4(t1) + move a0, v0 + jalr t2 + + bnez v0, 2f +#endif +1: + li a0, MESG(OS_EVENT_PI) + jal send_mesg +#if LIBULTRA_VERSION >= OS_VER_J +2: +#endif + beqz s1, NoMoreRcpInts + +dp: + andi t1, s1, 0x20 + beqz t1, NoMoreRcpInts + + andi s1, s1, 0x1f + + li t1, MI_CLR_DP_INTR + sw t1, PHYS_TO_K1(MI_INIT_MODE_REG) + + li a0, MESG(OS_EVENT_DP) + jal send_mesg + +NoMoreRcpInts: + and s0, s0, ~CAUSE_IP3 + b next_interrupt + +prenmi: + lw k1, THREAD_SR(k0) + + and k1, k1, ~CAUSE_IP5 + sw k1, THREAD_SR(k0) + la t1, __osShutdown + lw t2, 0(t1) + beqz t2, firstnmi + + and s0, s0, ~CAUSE_IP5 + b redispatch + +firstnmi: + li t2, 1 + sw t2, 0(t1) /* __osShutdown */ + li a0, MESG(OS_EVENT_PRENMI) + jal send_mesg + + and s0, s0, ~CAUSE_IP5 + lw t2, __osRunQueue + lw k1, THREAD_SR(t2) + and k1, k1, ~CAUSE_IP5 + sw k1, THREAD_SR(t2) + b redispatch + +sw2: + and t0, t0, ~CAUSE_SW2 +STAY2(mtc0 t0, C0_CAUSE) + + li a0, MESG(OS_EVENT_SW2) + jal send_mesg + + and s0, s0, ~CAUSE_SW2 + b next_interrupt + +sw1: + and t0, t0, ~CAUSE_SW1 +STAY2(mtc0 t0, C0_CAUSE) + + li a0, MESG(OS_EVENT_SW1) + jal send_mesg + + and s0, s0, ~CAUSE_SW1 + b next_interrupt + +handle_break: + li t1, OS_FLAG_CPU_BREAK + sh t1, THREAD_FLAGS(k0) + li a0, MESG(OS_EVENT_CPU_BREAK) + jal send_mesg + b redispatch + +redispatch: + lw t1, THREAD_PRI(k0) + lw t2, __osRunQueue + lw t3, THREAD_PRI(t2) + + bge t1, t3, enqueueRunning + + move a1, k0 + la a0, __osRunQueue + + jal __osEnqueueThread + + j __osDispatchThread + +enqueueRunning: + la t1, __osRunQueue + lw t2, MQ_MTQUEUE(t1) + sw t2, THREAD_NEXT(k0) + sw k0, MQ_MTQUEUE(t1) + j __osDispatchThread +panic: + sw k0, __osFaultedThread + li t1, OS_STATE_STOPPED + sh t1, THREAD_STATE(k0) + li t1, OS_FLAG_FAULT + sh t1, THREAD_FLAGS(k0) + +STAY2(mfc0 t2, C0_BADVADDR) + + sw t2, THREAD_BADVADDR(k0) + + li a0, MESG(OS_EVENT_FAULT) + jal send_mesg + j __osDispatchThread +END(__osException) + +LEAF(send_mesg) + move s2, ra + la t2, __osEventStateTab + addu t2, t2, a0 + lw t1, OS_EVENTSTATE_MESSAGE_QUEUE(t2) + beqz t1, send_done + + lw t3, MQ_VALIDCOUNT(t1) + lw ta0, MQ_MSGCOUNT(t1) + + bge t3, ta0, send_done + + lw ta1, MQ_FIRST(t1) + addu ta1, ta1, t3 + + rem ta1, ta1, ta0 + lw ta0, MQ_MSG(t1) + mul ta1, ta1, 4 + addu ta0, ta0, ta1 + lw ta1, OS_EVENTSTATE_MESSAGE(t2) + sw ta1, 0(ta0) /* msg[ta1] = */ + addiu t2, t3, 1 + sw t2, MQ_VALIDCOUNT(t1) + lw t2, MQ_MTQUEUE(t1) + lw t3, THREAD_NEXT(t2) + beqz t3, send_done + + move a0, t1 + jal __osPopThread + + move t2, v0 + + move a1, t2 + la a0, __osRunQueue + jal __osEnqueueThread +send_done: + jr s2 +END(send_mesg) + +LEAF(handle_CpU) /* coprocessor error */ + and t1, t0, CAUSE_CEMASK + srl t1, t1, CAUSE_CESHIFT + li t2, 1 /* cp1 error */ + bne t1, t2, panic + + /* enable cp1 (fpu) for this thread */ + li t1, 1 + sw t1, THREAD_FP(k0) + lw k1, THREAD_SR(k0) + or k1, k1, SR_CU1 + sw k1, THREAD_SR(k0) + b enqueueRunning +END(handle_CpU) + +LEAF(__osEnqueueAndYield) + lw a1, __osRunningThread +STAY2(mfc0 t0, C0_SR) + ori t0, t0, SR_EXL + sw t0, THREAD_SR(a1) + sd s0, THREAD_GP16(a1) + sd s1, THREAD_GP17(a1) + sd s2, THREAD_GP18(a1) + sd s3, THREAD_GP19(a1) + sd s4, THREAD_GP20(a1) + sd s5, THREAD_GP21(a1) + sd s6, THREAD_GP22(a1) + sd s7, THREAD_GP23(a1) + sd gp, THREAD_GP28(a1) + sd sp, THREAD_GP29(a1) + sd s8, THREAD_GP30(a1) + sd ra, THREAD_GP31(a1) + sw ra, THREAD_PC(a1) + lw k1, THREAD_FP(a1) + beqz k1, 1f + cfc1 k1, fcr31 + sw k1, THREAD_FPCSR(a1) + sdc1 $f20, THREAD_FP20(a1) + sdc1 $f22, THREAD_FP22(a1) + sdc1 $f24, THREAD_FP24(a1) + sdc1 $f26, THREAD_FP26(a1) + sdc1 $f28, THREAD_FP28(a1) + sdc1 $f30, THREAD_FP30(a1) +1: +#if LIBULTRA_VERSION > OS_VER_D + lw k1, THREAD_SR(a1) + andi t1, k1, SR_IMASK + beqz t1, 2f + + la t0, __OSGlobalIntMask + lw t0, 0(t0) + xor t0, t0, XOR_VALUE + andi t0, t0, SR_IMASK + or t1, t1, t0 + and k1, k1, ~SR_IMASK + or k1, k1, t1 + sw k1, THREAD_SR(a1) +2: +#endif + lw k1, PHYS_TO_K1(MI_INTR_MASK_REG) +#if LIBULTRA_VERSION > OS_VER_D + beqz k1, 3f + + la k0, __OSGlobalIntMask + lw k0, 0(k0) + + srl k0, k0, 0x10 + xor k0, k0, XOR_VALUE + andi k0, k0, 0x3f + lw t0, THREAD_RCP(a1) + and k0, k0, t0 + or k1, k1, k0 +3: +#endif + sw k1, THREAD_RCP(a1) + beqz a0, noEnqueue + jal __osEnqueueThread +noEnqueue: + j __osDispatchThread +END(__osEnqueueAndYield) + +/*__osEnqueueThread(OSThread **, OSThread *)*/ +LEAF(__osEnqueueThread) + move t9, a0 + lw t8, 0(a0) + lw ta3, THREAD_PRI(a1) + lw ta2, THREAD_PRI(t8) + blt ta2, ta3, 1f +2: + move t9, t8 + lw t8, THREAD_NEXT(t8) + lw ta2, THREAD_PRI(t8) + bge ta2, ta3, 2b +1: + lw t8, THREAD_NEXT(t9) + sw t8, THREAD_NEXT(a1) + sw a1, THREAD_NEXT(t9) + sw a0, THREAD_QUEUE(a1) + jr ra +END(__osEnqueueThread) + +LEAF(__osPopThread) + lw v0, 0(a0) /* a0 is OSThread** */ + lw t9, THREAD_NEXT(v0) + sw t9, 0(a0) + jr ra +END(__osPopThread) + +#if LIBULTRA_VERSION >= OS_VER_K +LEAF(__osNop) + jr ra +END(__osNop) +#endif + +LEAF(__osDispatchThread) + la a0, __osRunQueue + jal __osPopThread + sw v0, __osRunningThread + li t0, OS_STATE_RUNNING + sh t0, THREAD_STATE(v0) + move k0, v0 + +__osDispatchThreadSave: +#if LIBULTRA_VERSION > OS_VER_D + lw k1, THREAD_SR(k0) + la t0, __OSGlobalIntMask + lw t0, 0(t0) + andi t0, t0, SR_IMASK + andi t1, k1, SR_IMASK + and t1, t1, t0 + and k1, k1, ~SR_IMASK + or k1, k1, t1 +STAY2(mtc0 k1, C0_SR) +#endif +.set noat + ld $1, THREAD_GP1(k0) +.set at + ld $2, THREAD_GP2(k0) + ld $3, THREAD_GP3(k0) + ld $4, THREAD_GP4(k0) + ld $5, THREAD_GP5(k0) + ld $6, THREAD_GP6(k0) + ld $7, THREAD_GP7(k0) + ld $8, THREAD_GP8(k0) + ld $9, THREAD_GP9(k0) + ld $10, THREAD_GP10(k0) + ld $11, THREAD_GP11(k0) + ld $12, THREAD_GP12(k0) + ld $13, THREAD_GP13(k0) + ld $14, THREAD_GP14(k0) + ld $15, THREAD_GP15(k0) + ld $16, THREAD_GP16(k0) + ld $17, THREAD_GP17(k0) + ld $18, THREAD_GP18(k0) + ld $19, THREAD_GP19(k0) + ld $20, THREAD_GP20(k0) + ld $21, THREAD_GP21(k0) + ld $22, THREAD_GP22(k0) + ld $23, THREAD_GP23(k0) + ld $24, THREAD_GP24(k0) + ld $25, THREAD_GP25(k0) + ld $28, THREAD_GP28(k0) + ld $29, THREAD_GP29(k0) + ld $30, THREAD_GP30(k0) + ld $31, THREAD_GP31(k0) + ld k1, THREAD_LO(k0) + mtlo k1 + ld k1, THREAD_HI(k0) + mthi k1 + lw k1, THREAD_PC(k0) +STAY2(mtc0 k1, C0_EPC) +#if LIBULTRA_VERSION <= OS_VER_D + lw k1, THREAD_SR(k0) +STAY2(mtc0 k1, C0_SR) +#endif + lw k1, THREAD_FP(k0) + beqz k1, 1f + lw k1, THREAD_FPCSR(k0) +STAY2(ctc1 k1, fcr31) + ldc1 $f0, THREAD_FP0(k0) + ldc1 $f2, THREAD_FP2(k0) + ldc1 $f4, THREAD_FP4(k0) + ldc1 $f6, THREAD_FP6(k0) + ldc1 $f8, THREAD_FP8(k0) + ldc1 $f10, THREAD_FP10(k0) + ldc1 $f12, THREAD_FP12(k0) + ldc1 $f14, THREAD_FP14(k0) + ldc1 $f16, THREAD_FP16(k0) + ldc1 $f18, THREAD_FP18(k0) + ldc1 $f20, THREAD_FP20(k0) + ldc1 $f22, THREAD_FP22(k0) + ldc1 $f24, THREAD_FP24(k0) + ldc1 $f26, THREAD_FP26(k0) + ldc1 $f28, THREAD_FP28(k0) + ldc1 $f30, THREAD_FP30(k0) + + +/* IDO assembler throws an error due to eret instruction without noreorder */ +/* These were added only for IDO because iQue doesn't match with them */ +1: +#ifdef __sgi + .set noreorder +#endif + lw k1, THREAD_RCP(k0) +#if LIBULTRA_VERSION > OS_VER_D + la k0, __OSGlobalIntMask + lw k0, 0(k0) + srl k0, k0, 0x10 + and k1, k1, k0 +#endif + sll k1, k1, 0x1 + la k0, __osRcpImTable + addu k1, k1, k0 + lhu k1, 0(k1) + la k0, PHYS_TO_K1(MI_INTR_MASK_REG) + sw k1, 0(k0) + nop + nop + nop + nop + eret +#ifdef __sgi + .set reorder +#endif +END(__osDispatchThread) + +LEAF(__osCleanupThread) + move a0, zero + jal osDestroyThread +END(__osCleanupThread) diff --git a/lib/ultra/os/getcause.s b/lib/ultra/os/getcause.s new file mode 100644 index 00000000..873464f0 --- /dev/null +++ b/lib/ultra/os/getcause.s @@ -0,0 +1,9 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(__osGetCause) + STAY2(mfc0 v0, C0_CAUSE) + jr ra +END(__osGetCause) diff --git a/lib/ultra/os/getcount.s b/lib/ultra/os/getcount.s new file mode 100644 index 00000000..a848c428 --- /dev/null +++ b/lib/ultra/os/getcount.s @@ -0,0 +1,14 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text + +#ifndef BBPLAYER + +LEAF(osGetCount) + STAY2(mfc0 v0, C0_COUNT) + jr ra +END(osGetCount) + +#endif diff --git a/lib/ultra/os/getcurrfaultthread.c b/lib/ultra/os/getcurrfaultthread.c new file mode 100644 index 00000000..e0ff512c --- /dev/null +++ b/lib/ultra/os/getcurrfaultthread.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSThread *__osGetCurrFaultedThread() { + return __osActiveQueue; // should be __osFaultedThread +} diff --git a/lib/ultra/os/getsr.s b/lib/ultra/os/getsr.s new file mode 100644 index 00000000..bc9c767c --- /dev/null +++ b/lib/ultra/os/getsr.s @@ -0,0 +1,9 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(__osGetSR) + STAY2(mfc0 v0, C0_SR) + jr ra +END(__osGetSR) diff --git a/lib/src/osGetThreadPri.c b/lib/ultra/os/getthreadpri.c similarity index 74% rename from lib/src/osGetThreadPri.c rename to lib/ultra/os/getthreadpri.c index 43a0145b..b41c039f 100644 --- a/lib/src/osGetThreadPri.c +++ b/lib/ultra/os/getthreadpri.c @@ -1,8 +1,10 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" +#include "osint.h" OSPri osGetThreadPri(OSThread *thread) { if (thread == NULL) { thread = __osRunningThread; } + return thread->priority; } diff --git a/lib/src/osGetTime.c b/lib/ultra/os/gettime.c similarity index 78% rename from lib/src/osGetTime.c rename to lib/ultra/os/gettime.c index 45cef5ca..74c74200 100644 --- a/lib/src/osGetTime.c +++ b/lib/ultra/os/gettime.c @@ -1,7 +1,5 @@ -#include "libultra_internal.h" - -extern OSTime __osCurrentTime; -extern u32 __osBaseCounter; +#include "PR/os_internal.h" +#include "osint.h" OSTime osGetTime() { u32 tmpTime; diff --git a/lib/ultra/os/initialize.c b/lib/ultra/os/initialize.c new file mode 100644 index 00000000..e0d4b52a --- /dev/null +++ b/lib/ultra/os/initialize.c @@ -0,0 +1,203 @@ +#include "PR/os_internal.h" +#include "PR/R4300.h" +#include "PR/rcp.h" +#include "../io/piint.h" +#include "macros.h" +#ifdef BBPLAYER +#include "PR/bcp.h" +#endif + +typedef struct { + u32 inst1; + u32 inst2; + u32 inst3; + u32 inst4; +} __osExceptionVector; +extern __osExceptionVector __osExceptionPreamble; + +u64 osClockRate = OS_CLOCK_RATE; +#if LIBULTRA_VERSION >= OS_VER_H +u32 osViClock = VI_NTSC_CLOCK; +#endif +u32 __osShutdown = 0; +#if LIBULTRA_VERSION >= OS_VER_F +u32 __OSGlobalIntMask = OS_IM_ALL; +u32 __osLeoPresent = 0; +#endif +#ifdef _FINALROM +u32 __osFinalrom; +#endif + +#if LIBULTRA_VERSION >= OS_VER_K +void __createSpeedParam(void) { + __Dom1SpeedParam.type = DEVICE_TYPE_INIT; + __Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG); + __Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG); + __Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG); + __Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG); + + __Dom2SpeedParam.type = DEVICE_TYPE_INIT; + __Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG); + __Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG); + __Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG); + __Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG); +} +#endif + +void __osInitialize_common(void) { + u32 pifdata; +#if LIBULTRA_VERSION < OS_VER_K + u32 clock = 0; +#endif + +#ifdef _FINALROM + __osFinalrom = TRUE; +#endif + __osSetSR(__osGetSR() | SR_CU1); + __osSetFpcCsr(FPCSR_FS | FPCSR_EV); +#if LIBULTRA_VERSION >= OS_VER_K + __osSetWatchLo(0x4900000); +#endif +#ifdef BBPLAYER + { + u32 x = IO_WRITE(MI_3C_REG, 0x22000); + u32 y = IO_WRITE(MI_3C_REG, 0x11000); + __osBbIsBb = ((x & 0x140) == 0x140) && ((y & 0x140) == 0); + } + + if (__osBbIsBb && (IO_READ(PI_60_REG) & 0xC0000000)) { + __osBbIsBb = 2; + } + + if (__osBbIsBb) { + osTvType = OS_TV_NTSC; + osRomType = DEVICE_TYPE_CART; + osResetType = 0; + osVersion = 1; + osMemSize = 4 * 1024 * 1024; // 4MB RAM + } + + if (__osBbIsBb == 0) { +#endif + while (__osSiRawReadIo(PIF_RAM_END - 3, &pifdata)) { //last byte of joychannel ram + } + while (__osSiRawWriteIo(PIF_RAM_END - 3, pifdata | 8)) { //todo: magic constant + } +#ifdef BBPLAYER + } +#endif + + *(__osExceptionVector *) UT_VEC = __osExceptionPreamble; // TLB miss + *(__osExceptionVector *) XUT_VEC = __osExceptionPreamble; // XTLB miss + *(__osExceptionVector *) ECC_VEC = __osExceptionPreamble; // cache errors + *(__osExceptionVector *) E_VEC = __osExceptionPreamble; // general exceptions + + osWritebackDCache((void *) UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector)); + osInvalICache((void *) UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector)); +#if LIBULTRA_VERSION >= OS_VER_J + __createSpeedParam(); + osUnmapTLBAll(); +#endif + osMapTLBRdb(); + +#if LIBULTRA_VERSION < OS_VER_J + osPiRawReadIo(4, &clock); + clock &= ~0xf; + if (clock) { + osClockRate = clock; + } +#endif + osClockRate = osClockRate * 3 / 4; + + if (osResetType == 0) { // cold reset + bzero(osAppNMIBuffer, OS_APP_NMI_BUFSIZE); + } + +#if LIBULTRA_VERSION >= OS_VER_H + if (osTvType == OS_TV_PAL) { + osViClock = VI_PAL_CLOCK; + } else if (osTvType == OS_TV_MPAL) { + osViClock = VI_MPAL_CLOCK; + } else { + osViClock = VI_NTSC_CLOCK; + } +#elif LIBULTRA_VERSION == OS_VER_F + { + u32 leoStatus, status; + WAIT_ON_IO_BUSY(status); + + if (!((leoStatus = IO_READ(LEO_STATUS)) & LEO_STATUS_PRESENCE_MASK)) { + __osLeoPresent = 1; + __osSetHWIntrRoutine(1, __osLeoInterrupt); + } else { + __osLeoPresent = 0; + } + } +#endif +#if LIBULTRA_VERSION >= OS_VER_J + // Wait until there are no RCP interrupts + if (__osGetCause() & CAUSE_IP5) { + while (TRUE) { + } + } +#endif +#ifdef BBPLAYER + if (!__osBbIsBb) { // On iQue these are set before the game runs + __osBbEepromSize = 0x200; // 4K EEPROM size + __osBbPakSize = 0x8000; // SRAM size + __osBbFlashSize = 0x20000; // FlashRAM size + // iQue doesn't have a physical save chip, so store them in RAM + __osBbEepromAddress = (u8 *) (0x80400000 - 0x200); + __osBbPakAddress[0] = (u32 *)(0x80400000 - 0x8000 - 0x200); + __osBbPakAddress[1] = NULL; + __osBbPakAddress[2] = NULL; + __osBbPakAddress[3] = NULL; + __osBbFlashAddress = 0x80400000 - 0x20000; + __osBbSramSize = __osBbFlashSize; // 0x20000 + __osBbSramAddress = __osBbFlashAddress; // 0x80400000 - 0x20000 + } + if (__osBbIsBb) { + IO_WRITE(PI_64_REG, IO_READ(PI_64_REG) & 0x7FFFFFFF); + IO_WRITE(MI_3C_REG, 0x20000); + IO_WRITE(SI_0C_REG, 0); + IO_WRITE(SI_1C_REG, (IO_READ(SI_1C_REG) & 0x80FFFFFF) | 0x2F400000); + } +#endif +#if LIBULTRA_VERSION >= OS_VER_K + IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON); + IO_WRITE(AI_DACRATE_REG, AI_MAX_DAC_RATE - 1); + IO_WRITE(AI_BITRATE_REG, AI_MAX_BIT_RATE - 1); +#endif +} + +#if LIBULTRA_VERSION >= OS_VER_K +void __osInitialize_autodetect(void) { +#ifndef _FINALROM + if (__checkHardware_msp()) { + __osInitialize_msp(); + } else if (__checkHardware_kmc()) { + __osInitialize_kmc(); + } else if (__checkHardware_isv()) { + __osInitialize_isv(); + } else { + __osInitialize_emu(); + } +#endif +} +#endif + +#if LIBULTRA_VERSION == OS_VER_J +void createSpeedParam(void) { + __Dom1SpeedParam.type = DEVICE_TYPE_INIT; + __Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG); + __Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG); + __Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG); + __Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG); + + __Dom2SpeedParam.type = DEVICE_TYPE_INIT; + __Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG); + __Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG); + __Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG); + __Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG); +} +#endif diff --git a/lib/ultra/os/interrupt.s b/lib/ultra/os/interrupt.s new file mode 100644 index 00000000..a063c2bd --- /dev/null +++ b/lib/ultra/os/interrupt.s @@ -0,0 +1,50 @@ +#include "PR/R4300.h" +#include "PR/os.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +#ifdef BBPLAYER +.set mips2 +#endif + +.text +.set noreorder +LEAF(__osDisableInt) +#if LIBULTRA_VERSION >= OS_VER_J + la t2, __OSGlobalIntMask + lw t3, (t2) + andi t3, SR_IMASK +#endif + mfc0 t0, C0_SR + and t1, t0, ~SR_IE + mtc0 t1, C0_SR + andi v0, t0, SR_IE +#if LIBULTRA_VERSION >= OS_VER_J + lw t0, (t2) + andi t0, SR_IMASK + beq t0, t3, ret + la t2, __osRunningThread + lw t1, 280(t2) + andi t2, t1, SR_IMASK + and t2, t0 + and t1, ~SR_IMASK + or t1, t2 + and t1, ~SR_IE + mtc0 t1, $12 + nop +#endif + nop +ret: + jr ra + nop +END(__osDisableInt) + +LEAF(__osRestoreInt) + mfc0 t0, C0_SR + or t0, t0, a0 + mtc0 t0, C0_SR + nop + nop + jr ra + nop +END(__osRestoreInt) diff --git a/lib/ultra/os/invaldcache.s b/lib/ultra/os/invaldcache.s new file mode 100644 index 00000000..5b984fb8 --- /dev/null +++ b/lib/ultra/os/invaldcache.s @@ -0,0 +1,55 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(osInvalDCache) + blez a1, 3f + + li t3, DCACHE_SIZE + bgeu a1, t3, 4f + + move t0, a0 + addu t1, a0, a1 + bgeu t0, t1, 3f + + addiu t1, t1, -DCACHE_LINESIZE + andi t2, t0, DCACHE_LINEMASK + beqz t2, 1f + + subu t0, t0, t2 + CACHE((C_HWBINV|CACH_PD), (t0)) + bgeu t0, t1, 3f + + addiu t0, t0, DCACHE_LINESIZE +1: + andi t2, t1, DCACHE_LINEMASK + beqz t2, 2f + + subu t1, t1, t2 + CACHE((C_HWBINV|CACH_PD), 0x10(t1)) + bltu t1, t0, 3f + +2: + CACHE((C_HINV|CACH_PD), (t0)) + .set noreorder + bltu t0, t1, 2b + addiu t0, t0, DCACHE_LINESIZE + .set reorder +3: + jr ra + +4: + li t0, KUSIZE + addu t1, t0, t3 + addiu t1, t1, -DCACHE_LINESIZE +5: + CACHE((C_IINV|CACH_PD), (t0)) + .set noreorder + bltu t0, t1, 5b + addiu t0, t0, DCACHE_LINESIZE + .set reorder + + jr ra + +END(osInvalDCache) diff --git a/lib/ultra/os/invalicache.s b/lib/ultra/os/invalicache.s new file mode 100644 index 00000000..6c9e5b33 --- /dev/null +++ b/lib/ultra/os/invalicache.s @@ -0,0 +1,41 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(osInvalICache) + blez a1, 2f + + li t3, ICACHE_SIZE + bgeu a1, t3, 3f + + move t0, a0 + addu t1, a0, a1 + bgeu t0, t1, 2f + + addiu t1, t1, -ICACHE_LINESIZE + andi t2, t0, ICACHE_LINEMASK + subu t0, t0, t2 +1: + CACHE((C_HINV|CACH_PI), (t0)) + .set noreorder + bltu t0, t1, 1b + addiu t0, t0, ICACHE_LINESIZE + .set reorder +2: + jr ra + +3: + li t0, KUSIZE + addu t1, t0, t3 + addiu t1, t1, -ICACHE_LINESIZE +4: + CACHE((C_IINV|CACH_PI), (t0)) + .set noreorder + bltu t0, t1, 4b + addiu t0, t0, ICACHE_LINESIZE + .set reorder + + jr ra + +END(osInvalICache) diff --git a/lib/src/osJamMesg.c b/lib/ultra/os/jammesg.c similarity index 61% rename from lib/src/osJamMesg.c rename to lib/ultra/os/jammesg.c index a4b5e8ff..f9442d33 100644 --- a/lib/src/osJamMesg.c +++ b/lib/ultra/os/jammesg.c @@ -1,14 +1,15 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" +#include "osint.h" + +s32 osJamMesg(OSMesgQueue *mq, OSMesg msg, s32 flags) { + register s32 saveMask = __osDisableInt(); -s32 osJamMesg(OSMesgQueue *mq, OSMesg msg, s32 flag) { - register s32 int_disabled; - int_disabled = __osDisableInt(); while (MQ_IS_FULL(mq)) { - if (flag == OS_MESG_BLOCK) { + if (flags == OS_MESG_BLOCK) { __osRunningThread->state = OS_STATE_WAITING; __osEnqueueAndYield(&mq->fullqueue); } else { - __osRestoreInt(int_disabled); + __osRestoreInt(saveMask); return -1; } } @@ -16,9 +17,11 @@ s32 osJamMesg(OSMesgQueue *mq, OSMesg msg, s32 flag) { mq->first = (mq->first + mq->msgCount - 1) % mq->msgCount; mq->msg[mq->first] = msg; mq->validCount++; + if (mq->mtqueue->next != NULL) { osStartThread(__osPopThread(&mq->mtqueue)); } - __osRestoreInt(int_disabled); + + __osRestoreInt(saveMask); return 0; } diff --git a/lib/ultra/os/maptlb.s b/lib/ultra/os/maptlb.s new file mode 100644 index 00000000..84d2bf38 --- /dev/null +++ b/lib/ultra/os/maptlb.s @@ -0,0 +1,58 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +#define index a0 +#define pm a1 +#define vaddr a2 +#define evenpaddr a3 +#define oddpaddr 16(sp) +#define asid 20(sp) +.text +LEAF(osMapTLB) + STAY2(mfc0 t0, C0_ENTRYHI) + STAY2(mtc0 index, C0_INX) + STAY2(mtc0 pm, C0_PAGEMASK) +.set noreorder + lw t1, asid + beq t1, -1, 7f + li ta0, TLBLO_G +.set reorder + li t2, TLBLO_NONCOHRNT | TLBLO_D | TLBLO_V + or vaddr, vaddr, t1 + b 8f + +7: + li t2, TLBLO_NONCOHRNT | TLBLO_D | TLBLO_V | TLBLO_G +8: + STAY2(mtc0 vaddr, C0_ENTRYHI) + beq evenpaddr, -1, 9f + srl t3, evenpaddr, TLBLO_PFNSHIFT + or t3, t3, t2 + STAY2(mtc0 t3, C0_ENTRYLO0) + b 10f +9: + STAY2(mtc0 ta0, C0_ENTRYLO0) +10: + lw t3, oddpaddr + beq t3, -1, 11f + srl t3, t3, TLBLO_PFNSHIFT + or t3, t3, t2 + STAY2(mtc0 t3, C0_ENTRYLO1) + b 12f +11: + STAY2(mtc0 ta0, C0_ENTRYLO1) + bne evenpaddr, -1, 12f + li t3, K0BASE + STAY2(mtc0 t3, C0_ENTRYHI) +12: + .set noreorder + nop + tlbwi + nop + nop + nop + nop + STAY2(mtc0 t0, C0_ENTRYHI) + jr ra +END(osMapTLB) diff --git a/lib/ultra/os/maptlbrdb.s b/lib/ultra/os/maptlbrdb.s new file mode 100644 index 00000000..c004362b --- /dev/null +++ b/lib/ultra/os/maptlbrdb.s @@ -0,0 +1,30 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +.set noreorder +LEAF(osMapTLBRdb) + mfc0 t0, C0_ENTRYHI + li t1, 31 + mtc0 t1, C0_INX + mtc0 zero, C0_PAGEMASK /*4k*/ + li t2, TLBLO_UNCACHED | TLBLO_D | TLBLO_V | TLBLO_G + li t1, K2BASE + mtc0 t1, C0_ENTRYHI + li t1, KUSIZE + srl t3, t1,TLBLO_PFNSHIFT + or t3, t3,t2 + mtc0 t3, C0_ENTRYLO0 + li t1, TLBLO_G + mtc0 t1, C0_ENTRYLO1 + nop + tlbwi + nop + nop + nop + nop + mtc0 t0, C0_ENTRYHI + jr ra + nop +END(osMapTLBRdb) diff --git a/lib/src/osint.h b/lib/ultra/os/osint.h similarity index 82% rename from lib/src/osint.h rename to lib/ultra/os/osint.h index 0be4830b..a0c54d04 100644 --- a/lib/src/osint.h +++ b/lib/ultra/os/osint.h @@ -1,12 +1,16 @@ #ifndef _OSINT_H #define _OSINT_H -#include "libultra_internal.h" - +#include "PR/os_internal.h" typedef struct __OSEventState { OSMesgQueue *messageQueue; OSMesg message; } __OSEventState; +extern struct __osThreadTail +{ + OSThread *next; + OSPri priority; +} __osThreadTail; //maybe should be in exceptasm.h? extern void __osEnqueueAndYield(OSThread **); @@ -14,21 +18,18 @@ extern void __osDequeueThread(OSThread **, OSThread *); extern void __osEnqueueThread(OSThread **, OSThread *); extern OSThread *__osPopThread(OSThread **); extern void __osDispatchThread(void); +extern void __osCleanupThread(void); extern void __osSetTimerIntr(OSTime); extern OSTime __osInsertTimer(OSTimer *); extern void __osTimerInterrupt(void); extern u32 __osProbeTLB(void *); -extern int __osSpDeviceBusy(void); +extern int __osSpDeviceBusy(void); -#ifdef AVOID_UB -extern OSThread_ListHead __osThreadTail_fix; -#else extern OSThread *__osRunningThread; extern OSThread *__osActiveQueue; extern OSThread *__osFaultedThread; extern OSThread *__osRunQueue; -#endif extern OSTimer *__osTimerList; extern OSTimer __osBaseTimer; @@ -36,13 +37,13 @@ extern OSTime __osCurrentTime; extern u32 __osBaseCounter; extern u32 __osViIntrCount; extern u32 __osTimerCounter; +extern u32 __osShutdown; -extern __OSEventState __osEventStateTab[OS_NUM_EVENTS]; +extern __OSEventState __osEventStateTab[]; //not sure if this should be here extern s32 osViClock; -extern u32 __osShutdown; extern void __osTimerServicesInit(void); extern s32 __osAiDeviceBusy(void); extern int __osDpDeviceBusy(void); diff --git a/lib/ultra/os/parameters.s b/lib/ultra/os/parameters.s new file mode 100644 index 00000000..d6b3d048 --- /dev/null +++ b/lib/ultra/os/parameters.s @@ -0,0 +1,51 @@ +#include "PR/R4300.h" +#include "PR/os.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text + +ABS(leoBootID, 0x800001a0) +ABS(osTvType, 0x80000300) +ABS(osRomType, 0x80000304) +ABS(osRomBase, 0x80000308) +ABS(osResetType, 0x8000030c) +ABS(osCicId, 0x80000310) +ABS(osVersion, 0x80000314) +ABS(osMemSize, 0x80000318) +ABS(osAppNMIBuffer, 0x8000031c) + +#ifdef BBPLAYER +ABS(__osBbEepromAddress, 0x8000035c) +ABS(__osBbEepromSize, 0x80000360) +ABS(__osBbFlashAddress, 0x80000364) +ABS(__osBbFlashSize, 0x80000368) +ABS(__osBbSramAddress, 0x8000036c) +ABS(__osBbSramSize, 0x80000370) +ABS(__osBbPakAddress, 0x80000374) +ABS(__osBbPakSize, 0x80000384) +ABS(__osBbIsBb, 0x80000388) +ABS(__osBbHackFlags, 0x8000038c) +ABS(__osBbStashMagic, 0x80000390) +ABS(__osBbPakBindings, 0x80000394) +ABS(__osBbStateName, 0x800003a4) +ABS(__osBbStateDirty, 0x800003b4) +ABS(__osBbAuxDataLimit, 0x800003b8) + +/* padding */ +.fill 0x64 +#else +/* padding */ +/* JP is the only version without padding even though 2.0D has it (US) */ +#if (LIBULTRA_VERSION > OS_VER_D) || (LIBULTRA_VERSION == OS_VER_D && LIBULTRA_REVISION >= 1) +.repeat 0x34 +.byte 0 +.endr +#endif +#if LIBULTRA_VERSION >= OS_VER_H +.repeat 0x20 +.byte 0 +.endr +#endif + +#endif diff --git a/lib/ultra/os/probetlb.s b/lib/ultra/os/probetlb.s new file mode 100644 index 00000000..98a9a15a --- /dev/null +++ b/lib/ultra/os/probetlb.s @@ -0,0 +1,54 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +.set noreorder +LEAF(__osProbeTLB) + mfc0 t0, C0_ENTRYHI + andi t1, t0, TLBHI_PIDMASK + and t2, a0, TLBHI_VPN2MASK + or t1, t1, t2 + mtc0 t1, C0_ENTRYHI + nop + nop + nop + tlbp + nop + nop + mfc0 t3, C0_INX + and t3, t3, TLBINX_PROBE + bnez t3, 3f + nop + tlbr + nop + nop + nop + mfc0 t3, C0_PAGEMASK + addi t3, t3, DCACHE_SIZE + srl t3, t3, 0x1 + and ta0, t3, a0 + bnez ta0, 1f + addi t3, t3,-1 + mfc0 v0, C0_ENTRYLO0 + b 2f + nop +1: + mfc0 v0, C0_ENTRYLO1 +2: + andi ta1, v0,TLBLO_V + beqz ta1, 3f + nop + and v0, v0, TLBLO_PFNMASK + sll v0, v0, TLBLO_PFNSHIFT + and ta1, a0, t3 + add v0, v0, ta1 + b 4f + nop +3: + li v0, -1 +4: + mtc0 t0, C0_ENTRYHI + jr ra + nop +END(__osProbeTLB) diff --git a/lib/src/osRecvMesg.c b/lib/ultra/os/recvmesg.c similarity index 53% rename from lib/src/osRecvMesg.c rename to lib/ultra/os/recvmesg.c index db68e2cc..722e76ba 100644 --- a/lib/src/osRecvMesg.c +++ b/lib/ultra/os/recvmesg.c @@ -1,12 +1,12 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" +#include "osint.h" -s32 osRecvMesg(OSMesgQueue *mq, OSMesg *msg, s32 flag) { - register u32 int_disabled; - int_disabled = __osDisableInt(); +s32 osRecvMesg(OSMesgQueue *mq, OSMesg *msg, s32 flags) { + register u32 saveMask = __osDisableInt(); - while (!mq->validCount) { - if (!flag) { - __osRestoreInt(int_disabled); + while (MQ_IS_EMPTY(mq)) { + if (flags == OS_MESG_NOBLOCK) { + __osRestoreInt(saveMask); return -1; } else { __osRunningThread->state = OS_STATE_WAITING; @@ -15,7 +15,7 @@ s32 osRecvMesg(OSMesgQueue *mq, OSMesg *msg, s32 flag) { } if (msg != NULL) { - *msg = *(mq->first + mq->msg); + *msg = mq->msg[mq->first]; } mq->first = (mq->first + 1) % mq->msgCount; @@ -25,6 +25,6 @@ s32 osRecvMesg(OSMesgQueue *mq, OSMesg *msg, s32 flag) { osStartThread(__osPopThread(&mq->fullqueue)); } - __osRestoreInt(int_disabled); + __osRestoreInt(saveMask); return 0; } diff --git a/lib/ultra/os/resetglobalintmask.c b/lib/ultra/os/resetglobalintmask.c new file mode 100644 index 00000000..780da7cb --- /dev/null +++ b/lib/ultra/os/resetglobalintmask.c @@ -0,0 +1,9 @@ +#include "PR/os_internal.h" + +void __osResetGlobalIntMask(OSHWIntr mask) { + register u32 saveMask = __osDisableInt(); + + __OSGlobalIntMask &= ~(mask & ~OS_IM_RCP); + + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/os/sendmesg.c b/lib/ultra/os/sendmesg.c new file mode 100644 index 00000000..0ddf2654 --- /dev/null +++ b/lib/ultra/os/sendmesg.c @@ -0,0 +1,29 @@ +#include "PR/os_internal.h" +#include "osint.h" + +s32 osSendMesg(OSMesgQueue *mq, OSMesg msg, s32 flags) { + register u32 saveMask; + register s32 last; + saveMask = __osDisableInt(); + + while (MQ_IS_FULL(mq)) { + if (flags == OS_MESG_BLOCK) { + __osRunningThread->state = OS_STATE_WAITING; + __osEnqueueAndYield(&mq->fullqueue); + } else { + __osRestoreInt(saveMask); + return -1; + } + } + + last = (mq->first + mq->validCount) % mq->msgCount; + mq->msg[last] = msg; + mq->validCount++; + + if (mq->mtqueue->next != NULL) { + osStartThread(__osPopThread(&mq->mtqueue)); + } + + __osRestoreInt(saveMask); + return 0; +} diff --git a/lib/ultra/os/setcompare.s b/lib/ultra/os/setcompare.s new file mode 100644 index 00000000..9e7f0e47 --- /dev/null +++ b/lib/ultra/os/setcompare.s @@ -0,0 +1,14 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text + +#ifndef BBPLAYER + +LEAF(__osSetCompare) + STAY2(mtc0 a0, C0_COMPARE) + jr ra +END(__osSetCompare) + +#endif diff --git a/lib/ultra/os/seteventmesg.c b/lib/ultra/os/seteventmesg.c new file mode 100644 index 00000000..da0908e1 --- /dev/null +++ b/lib/ultra/os/seteventmesg.c @@ -0,0 +1,31 @@ +#include "PR/os_internal.h" +#include "osint.h" +#include "macros.h" + +ALIGNED8 __OSEventState __osEventStateTab[OS_NUM_EVENTS]; +#if LIBULTRA_VERSION >= OS_VER_J +u32 __osPreNMI = FALSE; +#endif + +void osSetEventMesg(OSEvent event, OSMesgQueue *mq, OSMesg msg) { + register u32 saveMask; + __OSEventState *es; + + saveMask = __osDisableInt(); + + es = &__osEventStateTab[event]; + + es->messageQueue = mq; + es->message = msg; + +#if LIBULTRA_VERSION >= OS_VER_J + if (event == OS_EVENT_PRENMI) { + if (__osShutdown && !__osPreNMI) { + osSendMesg(mq, msg, OS_MESG_NOBLOCK); + } + __osPreNMI = TRUE; + } +#endif + + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/os/setfpccsr.s b/lib/ultra/os/setfpccsr.s new file mode 100644 index 00000000..f96ab33a --- /dev/null +++ b/lib/ultra/os/setfpccsr.s @@ -0,0 +1,11 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(__osSetFpcCsr) + STAY2(cfc1 v0, fcr31) + STAY2(ctc1 a0, fcr31) + jr ra +END(__osSetFpcCsr) +.globl __osSetSR diff --git a/lib/src/__osSetGlobalIntMask.c b/lib/ultra/os/setglobalintmask.c similarity index 55% rename from lib/src/__osSetGlobalIntMask.c rename to lib/ultra/os/setglobalintmask.c index 937281cf..a7189807 100644 --- a/lib/src/__osSetGlobalIntMask.c +++ b/lib/ultra/os/setglobalintmask.c @@ -1,8 +1,9 @@ -#include "libultra_internal.h" -#include "PR/os.h" +#include "PR/os_internal.h" -void __osSetGlobalIntMask(s32 mask) { +void __osSetGlobalIntMask(OSHWIntr mask) { register u32 saveMask = __osDisableInt(); + __OSGlobalIntMask |= mask; + __osRestoreInt(saveMask); } diff --git a/lib/ultra/os/sethwinterrupt.c b/lib/ultra/os/sethwinterrupt.c new file mode 100644 index 00000000..15ddea96 --- /dev/null +++ b/lib/ultra/os/sethwinterrupt.c @@ -0,0 +1,30 @@ +#include "PR/os_internal.h" + +// A stack frame was added to hardware interrupt handlers in 2.0J +#if LIBULTRA_VERSION >= OS_VER_J +struct __osHwInt { + s32 (*handler)(void); + void* stackEnd; +}; + +extern struct __osHwInt __osHwIntTable[]; +#else +extern s32 (*__osHwIntTable[])(void); +#endif + +#if LIBULTRA_VERSION >= OS_VER_J +void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void), void* stackEnd) +#else +void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void)) +#endif +{ + register u32 saveMask = __osDisableInt(); + +#if LIBULTRA_VERSION >= OS_VER_J + __osHwIntTable[interrupt].handler = handler; + __osHwIntTable[interrupt].stackEnd = stackEnd; +#else + __osHwIntTable[interrupt] = handler; +#endif + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/os/setintmask.s b/lib/ultra/os/setintmask.s new file mode 100644 index 00000000..f5c95bae --- /dev/null +++ b/lib/ultra/os/setintmask.s @@ -0,0 +1,144 @@ +#include "PR/R4300.h" +#include "PR/rcp.h" +#include "PR/os.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +#define MI_INTR_MASK ((1 << 6) - 1) + +#ifdef BBPLAYER +#define XOR_VALUE 0xFFFFFFFF +#else +#define XOR_VALUE ~0 +#endif + +#if LIBULTRA_VERSION > OS_VER_D +#define RO_MOVE ta0 +#else +#define RO_MOVE t1 +#endif + +#ifdef BBPLAYER +.set mips2 +#endif + +.globl __osRcpImTable + +.text +.set noreorder +LEAF(osSetIntMask) + mfc0 RO_MOVE, C0_SR + + andi v0, RO_MOVE, OS_IM_CPU +#if LIBULTRA_VERSION > OS_VER_D + la t0, __OSGlobalIntMask + lw t3, 0(t0) + + xor t0, t3, XOR_VALUE + andi t0, t0,(SR_IMASK) + or v0, v0,t0 +#endif + lw t2, PHYS_TO_K1(MI_INTR_MASK_REG) +#if LIBULTRA_VERSION > OS_VER_D + beqz t2, 1f + srl t1, t3,0x10 + xor t1, t1, XOR_VALUE + andi t1, t1, MI_INTR_MASK + or t2, t2,t1 +1: +#endif + sll t2, t2,0x10 + or v0, v0,t2 + + and t0, a0, MI_INTR_MASK<<0x10 +#if LIBULTRA_VERSION > OS_VER_D + and t0, t0,t3 +#endif + srl t0, t0,0xf + lhu t2, __osRcpImTable(t0) + sw t2, PHYS_TO_K1(MI_INTR_MASK_REG) + + andi t0, a0, OS_IM_CPU +#if LIBULTRA_VERSION > OS_VER_D + andi t1, t3, SR_IMASK + and t0, t0,t1 +#endif + and RO_MOVE, RO_MOVE, ~SR_IMASK + or RO_MOVE, RO_MOVE,t0 + + mtc0 RO_MOVE, C0_SR + nop + nop + jr ra + nop +END(osSetIntMask) + +.rdata +EXPORT(__osRcpImTable) +/* LUT to convert between MI_INTR and MI_INTR_MASK */ +/* MI_INTR is status for each interrupt whereas */ +/* MI_INTR_MASK has seperate bits for set/clr */ +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +.half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP diff --git a/lib/ultra/os/setsr.s b/lib/ultra/os/setsr.s new file mode 100644 index 00000000..0efa9154 --- /dev/null +++ b/lib/ultra/os/setsr.s @@ -0,0 +1,10 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(__osSetSR) + STAY2(mtc0 a0, C0_SR) + STAY1(nop) + jr ra +END(__osSetSR) diff --git a/lib/ultra/os/setthreadpri.c b/lib/ultra/os/setthreadpri.c new file mode 100644 index 00000000..caaa4611 --- /dev/null +++ b/lib/ultra/os/setthreadpri.c @@ -0,0 +1,25 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osSetThreadPri(OSThread *t, OSPri pri) { + register u32 saveMask = __osDisableInt(); + + if (t == NULL) { + t = __osRunningThread; + } + + if (t->priority != pri) { + t->priority = pri; + if (t != __osRunningThread && t->state != OS_STATE_STOPPED) { + __osDequeueThread(t->queue, t); + __osEnqueueThread(t->queue, t); + } + + if (__osRunningThread->priority < __osRunQueue->priority) { + __osRunningThread->state = OS_STATE_RUNNABLE; + __osEnqueueAndYield(&__osRunQueue); + } + } + + __osRestoreInt(saveMask); +} diff --git a/lib/ultra/os/settime.c b/lib/ultra/os/settime.c new file mode 100644 index 00000000..5bae2a24 --- /dev/null +++ b/lib/ultra/os/settime.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osSetTime(OSTime time) { + __osCurrentTime = time; +} diff --git a/lib/ultra/os/settimer.c b/lib/ultra/os/settimer.c new file mode 100644 index 00000000..02259645 --- /dev/null +++ b/lib/ultra/os/settimer.c @@ -0,0 +1,50 @@ +#include "PR/os_internal.h" +#include "osint.h" +#include "macros.h" + +u32 osSetTimer(OSTimer *t, OSTime countdown, OSTime interval, OSMesgQueue *mq, OSMesg msg) { +#if LIBULTRA_VERSION >= OS_VER_K + UNUSED OSTime time; + OSTimer *next; + u32 count; + u32 value; + u32 saveMask; +#else + OSTime time; +#endif + + t->next = NULL; + t->prev = NULL; + t->interval = interval; + t->value = (countdown != 0) ? countdown : interval; + t->mq = mq; + t->msg = msg; + +#if LIBULTRA_VERSION >= OS_VER_K + saveMask = __osDisableInt(); + if (__osTimerList->next == __osTimerList) { + } else { + next = __osTimerList->next; + count = osGetCount(); + value = count - __osTimerCounter; + + if (value < next->value) { + next->value -= value; + } else { + next->value = 1; + } + } + + time = __osInsertTimer(t); + __osSetTimerIntr(__osTimerList->next->value); + + __osRestoreInt(saveMask); +#else + time = __osInsertTimer(t); + if (__osTimerList->next == t) { + __osSetTimerIntr(time); + } +#endif + + return 0; +} diff --git a/lib/ultra/os/setwatchlo.s b/lib/ultra/os/setwatchlo.s new file mode 100644 index 00000000..b72cfd2a --- /dev/null +++ b/lib/ultra/os/setwatchlo.s @@ -0,0 +1,10 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(__osSetWatchLo) + STAY2(mtc0 a0, C0_WATCHLO) + STAY1(nop) + jr ra +END(__osSetWatchLo) diff --git a/lib/ultra/os/startthread.c b/lib/ultra/os/startthread.c new file mode 100644 index 00000000..dc1dcee7 --- /dev/null +++ b/lib/ultra/os/startthread.c @@ -0,0 +1,32 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osStartThread(OSThread *t) { + register u32 saveMask = __osDisableInt(); + + switch (t->state) { + case OS_STATE_WAITING: + t->state = OS_STATE_RUNNABLE; + __osEnqueueThread(&__osRunQueue, t); + break; + case OS_STATE_STOPPED: + if (t->queue == NULL || t->queue == &__osRunQueue) { + t->state = OS_STATE_RUNNABLE; + __osEnqueueThread(&__osRunQueue, t); + } else { + t->state = OS_STATE_WAITING; + __osEnqueueThread(t->queue, t); + __osEnqueueThread(&__osRunQueue, __osPopThread(t->queue)); + } + break; + } + + if (__osRunningThread == NULL) { + __osDispatchThread(); + } else if (__osRunningThread->priority < __osRunQueue->priority) { + __osRunningThread->state = OS_STATE_RUNNABLE; + __osEnqueueAndYield(&__osRunQueue); + } + + __osRestoreInt(saveMask); +} diff --git a/lib/src/__osSyncPutChars.c b/lib/ultra/os/syncputchars.c similarity index 92% rename from lib/src/__osSyncPutChars.c rename to lib/ultra/os/syncputchars.c index 0defdbcc..017b7310 100644 --- a/lib/src/__osSyncPutChars.c +++ b/lib/ultra/os/syncputchars.c @@ -1,4 +1,4 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/rdb.h" #include "PR/R4300.h" @@ -17,17 +17,15 @@ void __osSyncPutChars(s32 type, s32 length, u8 *buf) { } while (!__osAtomicDec(&__osRdbWriteOK)) { - ; } mask = __osDisableInt(); - *(u32 *) RDB_BASE_REG = *(u32 *) &packet; + while (!(__osGetCause() & CAUSE_IP6)) { - ; } + *(u32 *) RDB_READ_INTR_REG = 0; __osRdbWriteOK++; - __osRestoreInt(mask); } diff --git a/lib/ultra/os/thread.c b/lib/ultra/os/thread.c new file mode 100644 index 00000000..31f0f91e --- /dev/null +++ b/lib/ultra/os/thread.c @@ -0,0 +1,25 @@ +#include "PR/os_internal.h" +#include "osint.h" + +struct __osThreadTail __osThreadTail = { NULL, -1 }; +OSThread *__osRunQueue = (OSThread *) &__osThreadTail; +OSThread *__osActiveQueue = (OSThread *) &__osThreadTail; +OSThread *__osRunningThread = { 0 }; +OSThread *__osFaultedThread = { 0 }; + +void __osDequeueThread(register OSThread **queue, register OSThread *t) { + register OSThread *pred; + register OSThread *succ; + + pred = (OSThread *) queue; + succ = pred->next; + + while (succ != NULL) { + if (succ == t) { + pred->next = t->next; + return; + } + pred = succ; + succ = pred->next; + } +} diff --git a/lib/ultra/os/threadasm.h b/lib/ultra/os/threadasm.h new file mode 100644 index 00000000..dfd91b6f --- /dev/null +++ b/lib/ultra/os/threadasm.h @@ -0,0 +1,68 @@ +#ifndef _THREADASM_H_ +#define _THREADASM_H_ + +/* Offsets of members in the OSThread struct */ +#define THREAD_NEXT 0 +#define THREAD_PRI 4 +#define THREAD_QUEUE 8 +#define THREAD_TLNEXT 12 +#define THREAD_STATE 16 +#define THREAD_FLAGS 18 +#define THREAD_ID 20 +#define THREAD_FP 24 +#define THREAD_GP1 32 +#define THREAD_GP2 40 +#define THREAD_GP3 48 +#define THREAD_GP4 56 +#define THREAD_GP5 64 +#define THREAD_GP6 72 +#define THREAD_GP7 80 +#define THREAD_GP8 88 +#define THREAD_GP9 96 +#define THREAD_GP10 104 +#define THREAD_GP11 112 +#define THREAD_GP12 120 +#define THREAD_GP13 128 +#define THREAD_GP14 136 +#define THREAD_GP15 144 +#define THREAD_GP16 152 +#define THREAD_GP17 160 +#define THREAD_GP18 168 +#define THREAD_GP19 176 +#define THREAD_GP20 184 +#define THREAD_GP21 192 +#define THREAD_GP22 200 +#define THREAD_GP23 208 +#define THREAD_GP24 216 +#define THREAD_GP25 224 +/* k0 and k1 are reserved for the kernel */ +#define THREAD_GP28 232 +#define THREAD_GP29 240 +#define THREAD_GP30 248 +#define THREAD_GP31 256 +#define THREAD_LO 264 +#define THREAD_HI 272 +#define THREAD_SR 280 +#define THREAD_PC 284 +#define THREAD_CAUSE 288 +#define THREAD_BADVADDR 292 +#define THREAD_RCP 296 +#define THREAD_FPCSR 300 +#define THREAD_FP0 304 +#define THREAD_FP2 312 +#define THREAD_FP4 320 +#define THREAD_FP6 328 +#define THREAD_FP8 336 +#define THREAD_FP10 344 +#define THREAD_FP12 352 +#define THREAD_FP14 360 +#define THREAD_FP16 368 +#define THREAD_FP18 376 +#define THREAD_FP20 384 +#define THREAD_FP22 392 +#define THREAD_FP24 400 +#define THREAD_FP26 408 +#define THREAD_FP28 416 +#define THREAD_FP30 424 + +#endif diff --git a/lib/src/osTimer.c b/lib/ultra/os/timerintr.c similarity index 66% rename from lib/src/osTimer.c rename to lib/ultra/os/timerintr.c index a9dbbc20..8a590743 100644 --- a/lib/src/osTimer.c +++ b/lib/ultra/os/timerintr.c @@ -1,20 +1,21 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" +#include "osint.h" OSTimer __osBaseTimer; -OSTimer *__osTimerList = &__osBaseTimer; OSTime __osCurrentTime; u32 __osBaseCounter; u32 __osViIntrCount; u32 __osTimerCounter; +OSTimer *__osTimerList = &__osBaseTimer; void __osTimerServicesInit(void) { __osCurrentTime = 0; __osBaseCounter = 0; __osViIntrCount = 0; __osTimerList->next = __osTimerList->prev = __osTimerList; - __osTimerList->interval = __osTimerList->remaining = 0; + __osTimerList->interval = __osTimerList->value = 0; __osTimerList->mq = NULL; - __osTimerList->msg = NULL; + __osTimerList->msg = 0; } void __osTimerInterrupt(void) { @@ -28,66 +29,77 @@ void __osTimerInterrupt(void) { for (;;) { t = __osTimerList->next; + if (t == __osTimerList) { __osSetCompare(0); __osTimerCounter = 0; break; } + count = osGetCount(); elapsedCycles = count - __osTimerCounter; __osTimerCounter = count; - if (elapsedCycles < t->remaining) { - t->remaining -= elapsedCycles; - __osSetTimerIntr(t->remaining); + + if (elapsedCycles < t->value) { + t->value -= elapsedCycles; + __osSetTimerIntr(t->value); break; } + t->prev->next = t->next; t->next->prev = t->prev; t->next = NULL; t->prev = NULL; + if (t->mq != NULL) { osSendMesg(t->mq, t->msg, OS_MESG_NOBLOCK); } + if (t->interval != 0) { - t->remaining = t->interval; + t->value = t->interval; __osInsertTimer(t); } } } -void __osSetTimerIntr(OSTime time) { +void __osSetTimerIntr(OSTime tim) { OSTime newTime; - s32 savedMask; -#ifdef VERSION_CN - if (time < 468) { - time = 468; + u32 savedMask; + +#if LIBULTRA_VERSION >= OS_VER_K + if (tim < 468) { + tim = 468; } #endif + savedMask = __osDisableInt(); __osTimerCounter = osGetCount(); - newTime = __osTimerCounter + time; + newTime = __osTimerCounter + tim; __osSetCompare(newTime); __osRestoreInt(savedMask); } OSTime __osInsertTimer(OSTimer *t) { OSTimer *timep; - OSTime time; - s32 savedMask; + OSTime tim; + u32 savedMask = __osDisableInt(); - savedMask = __osDisableInt(); - for (timep = __osTimerList->next, time = t->remaining; timep != __osTimerList && time > timep->remaining; - time -= timep->remaining, timep = timep->next) { - ; + timep = __osTimerList->next; + tim = t->value; + for (; timep != __osTimerList && tim > timep->value; timep = timep->next) { + tim -= timep->value; } - t->remaining = time; + + t->value = tim; + if (timep != __osTimerList) { - timep->remaining -= time; + timep->value -= tim; } + t->next = timep; t->prev = timep->prev; timep->prev->next = t; timep->prev = t; __osRestoreInt(savedMask); - return time; + return tim; } diff --git a/lib/ultra/os/unmaptlball.s b/lib/ultra/os/unmaptlball.s new file mode 100644 index 00000000..4846b004 --- /dev/null +++ b/lib/ultra/os/unmaptlball.s @@ -0,0 +1,35 @@ +#include "PR/R4300.h" +#include "PR/os.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +.set noreorder +LEAF(osUnmapTLBAll) + mfc0 t0, C0_ENTRYHI +#if LIBULTRA_VERSION >= OS_VER_I + li t1, NTLBENTRIES-1 /* last reserved for rdb */ +#else + li t1, NTLBENTRIES +#endif + li t2, KUSIZE + mtc0 t2, C0_ENTRYHI + mtc0 zero, C0_ENTRYLO0 + mtc0 zero, C0_ENTRYLO1 +1: + mtc0 t1, C0_INX + nop + tlbwi + nop + nop + addi t1, t1,-1 +#if LIBULTRA_VERSION >= OS_VER_I + bgez t1, 1b +#else + bnezl t1, 1b +#endif + nop + mtc0 t0, C0_ENTRYHI + jr ra + nop +END(osUnmapTLBAll) diff --git a/lib/src/osVirtualToPhysical.c b/lib/ultra/os/virtualtophysical.c similarity index 84% rename from lib/src/osVirtualToPhysical.c rename to lib/ultra/os/virtualtophysical.c index b6e3d2db..829f734e 100644 --- a/lib/src/osVirtualToPhysical.c +++ b/lib/ultra/os/virtualtophysical.c @@ -1,5 +1,6 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" #include "PR/R4300.h" +#include "osint.h" uintptr_t osVirtualToPhysical(void *addr) { if (IS_KSEG0(addr)) { diff --git a/lib/ultra/os/writebackdcache.s b/lib/ultra/os/writebackdcache.s new file mode 100644 index 00000000..e7b1daa4 --- /dev/null +++ b/lib/ultra/os/writebackdcache.s @@ -0,0 +1,34 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +LEAF(osWritebackDCache) + blez a1, 2f + li t3, DCACHE_SIZE + bgeu a1, t3, 3f + move t0, a0 + addu t1, a0, a1 + bgeu t0, t1, 2f + addiu t1, t1, -DCACHE_LINESIZE + andi t2, t0, DCACHE_LINEMASK + subu t0, t0, t2 +1: + CACHE( (C_HWB|CACH_PD), (t0)) + .set noreorder + bltu t0, t1, 1b + addiu t0, t0, DCACHE_LINESIZE + .set reorder +2: + jr ra +3: + li t0, KUSIZE + addu t1, t0, t3 + addiu t1, t1, -DCACHE_LINESIZE +4: + CACHE( (C_IWBINV|CACH_PD), (t0)) + .set noreorder + bltu t0, t1, 4b + addiu t0, t0, DCACHE_LINESIZE + .set reorder + jr ra +END(osWritebackDCache) diff --git a/lib/ultra/os/writebackdcacheall.s b/lib/ultra/os/writebackdcacheall.s new file mode 100644 index 00000000..7b05cdc1 --- /dev/null +++ b/lib/ultra/os/writebackdcacheall.s @@ -0,0 +1,18 @@ +#include "PR/R4300.h" +#include "sys/asm.h" +#include "sys/regdef.h" + +.text +LEAF(osWritebackDCacheAll) + li t0, KUSIZE + li t2, DCACHE_SIZE + addu t1, t0, t2 + addiu t1, t1, -DCACHE_LINESIZE +1: + CACHE( (C_IWBINV | CACH_PD), (t0)) + .set noreorder + bltu t0, t1, 1b + addiu t0, t0, DCACHE_LINESIZE + .set reorder + jr ra +END(osWritebackDCacheAll) diff --git a/lib/src/osYieldThread.c b/lib/ultra/os/yieldthread.c similarity index 80% rename from lib/src/osYieldThread.c rename to lib/ultra/os/yieldthread.c index 1685890e..9a4dafb8 100644 --- a/lib/src/osYieldThread.c +++ b/lib/ultra/os/yieldthread.c @@ -1,7 +1,9 @@ -#include "libultra_internal.h" +#include "PR/os_internal.h" +#include "osint.h" void osYieldThread(void) { register u32 saveMask = __osDisableInt(); + __osRunningThread->state = OS_STATE_RUNNABLE; __osEnqueueAndYield(&__osRunQueue); __osRestoreInt(saveMask); diff --git a/lib/ultra/vimodes/vimodempallan1.c b/lib/ultra/vimodes/vimodempallan1.c new file mode 100644 index 00000000..bd70a2a4 --- /dev/null +++ b/lib/ultra/vimodes/vimodempallan1.c @@ -0,0 +1,34 @@ +#include "PR/os.h" +#include "PR/rcp.h" + +OSViMode osViModeMpalLan1 = { + OS_VI_MPAL_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 30, 5, 70), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3089, 4), // hSync + OS_VI_LEAP(3097, 3098), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } +}; diff --git a/lib/ultra/vimodes/vimodentsclan1.c b/lib/ultra/vimodes/vimodentsclan1.c new file mode 100644 index 00000000..b7aae9c1 --- /dev/null +++ b/lib/ultra/vimodes/vimodentsclan1.c @@ -0,0 +1,34 @@ +#include "PR/os.h" +#include "PR/rcp.h" + +OSViMode osViModeNtscLan1 = { + OS_VI_NTSC_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(57, 34, 5, 62), // burst + OS_VI_VSYNC(525), // vSync + OS_VI_HSYNC(3093, 0), // hSync + OS_VI_LEAP(3093, 3093), // leap + OS_VI_HSTART(108, 748), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(37, 511), // vStart + OS_VI_BURST(4, 2, 14, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } +}; diff --git a/lib/ultra/vimodes/vimodepallan1.c b/lib/ultra/vimodes/vimodepallan1.c new file mode 100644 index 00000000..15cbd6ed --- /dev/null +++ b/lib/ultra/vimodes/vimodepallan1.c @@ -0,0 +1,34 @@ +#include "PR/os.h" +#include "PR/rcp.h" + +OSViMode osViModePalLan1 = { + OS_VI_PAL_LAN1, // type + { // comRegs + VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | + VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 | VI_CTRL_PIXEL_ADV_3, // ctrl + OS_VI_WIDTH(320), // width + OS_VI_BURST(58, OS_VI_BURST_CW_PAL, 4, OS_VI_BURST_CS_PAL), // burst + OS_VI_VSYNC(625), // vSync + OS_VI_HSYNC(3177, OS_VI_HSYNC_LEAP_PAL), // hSync + OS_VI_LEAP(3183, OS_VI_LEAP_LOWER_PAL), // leap + OS_VI_HSTART(128, 768), // hStart + OS_VI_SCALE(2, 0), // xScale + OS_VI_VCURRENT(0), // vCurrent + }, + { // fldRegs + { // [0] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + }, + { // [1] + OS_VI_ORIGIN(640), // origin + OS_VI_SCALE(1, 0), // yScale + OS_VI_HSTART(95, 569), // vStart + OS_VI_BURST(107, 2, 9, 0), // vBurst + OS_VI_VINTR(2), // vIntr + } + } +}; diff --git a/libultra.mk b/libultra.mk new file mode 100644 index 00000000..527fdd87 --- /dev/null +++ b/libultra.mk @@ -0,0 +1,175 @@ +ifeq ($(VERSION),jp) + LIBULTRA ?= D +else ifeq ($(VERSION),us) + LIBULTRA ?= D + LIBULTRA_REVISION ?= 1 +else ifeq ($(VERSION),eu) + LIBULTRA ?= F +else ifeq ($(VERSION),sh) + LIBULTRA ?= H +else ifeq ($(VERSION),cn) + LIBULTRA ?= BB +endif + +# Libultra number revision (only used on 2.0D) +LIBULTRA_REVISION ?= 0 + +# Special define for exclusive libultra files (driverominit) +LIBULTRA_EXCLUSIVE ?= 0 + +# LIBULTRA - sets the libultra OS version to use +$(eval $(call validate-option,LIBULTRA,D F H I K L BB)) + +ULTRA_VER_D := 1 +ULTRA_VER_E := 2 +ULTRA_VER_F := 3 +ULTRA_VER_G := 4 +ULTRA_VER_H := 5 +ULTRA_VER_I := 6 +ULTRA_VER_J := 7 +ULTRA_VER_K := 8 +ULTRA_VER_L := 9 + +ifeq ($(LIBULTRA),BB) + ULTRA_SRC_DIRS := $(shell find lib/ultra -type d) + ULTRA_VER_DEF := -DLIBULTRA_VERSION=$(ULTRA_VER_L) -DBBPLAYER -DLIBULTRA_STR_VER=\"L\" + LIBGULTRA ?= 1 +else + ULTRA_SRC_DIRS := $(shell find lib/ultra -type d -not -path "lib/ultra/bb/*") + ULTRA_VER_DEF := -DLIBULTRA_VERSION=$(ULTRA_VER_$(LIBULTRA)) -DLIBULTRA_REVISION=$(LIBULTRA_REVISION) -DLIBULTRA_STR_VER=\"$(LIBULTRA)\" +endif + +DEF_INC_CFLAGS += $(ULTRA_VER_DEF) + +ifeq ($(NON_MATCHING),1) + LIBULTRA_EXCLUSIVE := 1 + DEF_INC_CFLAGS += -DLIBULTRA_EXCLUSIVE +endif + +# LIBGULTRA - whenever to compile libultra using IDO or GNU +# 1 - uses egcs to match iQue (uses gcc if COMPILER is gcc) +# 0 - uses ido, used to match JP, US, EU and Shindou +LIBGULTRA ?= 0 +$(eval $(call validate-option,LIBGULTRA,0 1)) + +ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c)) +ULTRA_S_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.s)) + +ULTRA_O_C_FILES := $(foreach file,$(ULTRA_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) +ULTRA_O_AS_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) + +ULTRA_O_FILES := $(ULTRA_O_C_FILES) $(ULTRA_O_AS_FILES) + +DEP_FILES += $(ULTRA_O_FILES:.o=.d) + +LIBULTRA_AR := $(BUILD_DIR)/libultra.a + +libultra: $(LIBULTRA_AR) + +REG_SIZES := -mgp32 +NOABICALL := -mno-abicalls + +OPT_FLAGS_LIBC := +ifeq ($(LIBULTRA),BB) + OPT_FLAGS_LIBC := -O2 +else + ifneq ($(LIBULTRA),D) + OPT_FLAGS_LIBC := -O3 + endif +endif + +ULTRA_CC := $(CC) +ULTRA_CFLAGS = -non_shared -Wab,-r4300_mul -Xcpluscomm -Xfullwarn -G 0 -signed -32 +ULTRA_ASFLAGS = -non_shared -Wab,-r4300_mul -Xcpluscomm -Xfullwarn -G 0 -nostdinc -o32 -c + +GULTRA_CC := COMPILER_PATH=$(EGCS_PATH) $(EGCS_PATH)/gcc +GULTRA_CFLAGS = -mcpu=r4300 -fno-pic -Wa,--strip-local-absolute -G 0 +GULTRA_ASFLAGS = -mcpu=r4300 -fno-pic -x assembler-with-cpp -c -DEGCS_GCC + +ifeq ($(LIBGULTRA),1) + $(ULTRA_O_C_FILES): CC := $(GULTRA_CC) + $(ULTRA_O_C_FILES): CFLAGS = $(GULTRA_CFLAGS) $(NOABICALL) $(REG_SIZES) + + $(ULTRA_O_AS_FILES): AS := $(GULTRA_CC) + $(ULTRA_O_AS_FILES): ASFLAGS = $(GULTRA_ASFLAGS) + $(ULTRA_O_AS_FILES): MIPSISET := +else + $(ULTRA_O_C_FILES): CC := $(ULTRA_CC) + $(ULTRA_O_C_FILES): CFLAGS = $(ULTRA_CFLAGS) + + $(ULTRA_O_AS_FILES): AS := $(ULTRA_CC) + $(ULTRA_O_AS_FILES): ASFLAGS = $(ULTRA_ASFLAGS) + $(ULTRA_O_AS_FILES): OPT_FLAGS := + $(ULTRA_O_AS_FILES): MIPSISET := -mips2 +endif + +# Libultra specific flags +ifneq ($(LIBULTRA),BB) + $(BUILD_DIR)/lib/ultra/os/exceptasm.o: MIPSISET := -mips3 + $(BUILD_DIR)/lib/ultra/libc/%.o: ASOPT_FLAGS := -O2 + $(BUILD_DIR)/lib/ultra/libc/ll.o: MIPSISET := -mips3 -32 + $(BUILD_DIR)/lib/ultra/libc/ll%.o: MIPSISET := -mips3 -32 +endif + +ifeq ($(NON_MATCHING),0) + $(BUILD_DIR)/lib/ultra/%.o: OPT_FLAGS := + + $(BUILD_DIR)/lib/ultra/audio/bnkf.o: OPT_FLAGS := -O3 + $(BUILD_DIR)/lib/ultra/gu/%.o: OPT_FLAGS := -O3 + + $(BUILD_DIR)/lib/ultra/libc/ldiv.o: OPT_FLAGS := -O2 + $(BUILD_DIR)/lib/ultra/libc/string.o: OPT_FLAGS := -O2 + + $(BUILD_DIR)/lib/ultra/libc/sprintf.o: OPT_FLAGS := $(OPT_FLAGS_LIBC) + $(BUILD_DIR)/lib/ultra/libc/syncprintf.o: OPT_FLAGS := $(OPT_FLAGS_LIBC) + $(BUILD_DIR)/lib/ultra/libc/xlitob.o: OPT_FLAGS := $(OPT_FLAGS_LIBC) + $(BUILD_DIR)/lib/ultra/libc/xldtob.o: OPT_FLAGS := $(OPT_FLAGS_LIBC) + $(BUILD_DIR)/lib/ultra/libc/xprintf.o: OPT_FLAGS := $(OPT_FLAGS_LIBC) + + ifeq ($(LIBULTRA),BB) + $(BUILD_DIR)/lib/ultra/%.o: MIPSISET := + + $(BUILD_DIR)/lib/ultra/bb/os/%.o: MIPSISET := -mips3 + $(BUILD_DIR)/lib/ultra/bb/os/%.o: REG_SIZES := -mgp64 + + $(BUILD_DIR)/lib/ultra/bb/wrapper.o: NOABICALL := + $(BUILD_DIR)/lib/ultra/bb/wrapper.o: OPT_FLAGS := -O2 + + $(BUILD_DIR)/lib/ultra/gu/%.o: MIPSISET := -mips2 + $(BUILD_DIR)/lib/ultra/gu/%.o: OPT_FLAGS := -O2 + + $(BUILD_DIR)/lib/ultra/io/%.o: MIPSISET := -mips2 + $(BUILD_DIR)/lib/ultra/io/%.o: OPT_FLAGS := -O2 + + $(BUILD_DIR)/lib/ultra/libc/%.o: MIPSISET := -mips2 + + $(BUILD_DIR)/lib/ultra/os/%.o: MIPSISET := -mips2 + $(BUILD_DIR)/lib/ultra/os/%.o: ASOPT_FLAGS := -O2 + endif +endif + +$(BUILD_DIR)/lib/ultra/%.o: lib/ultra/%.c + $(call print,Compiling:,$<,$@) + $(V)$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/lib/ultra/$*.d $< + $(V)$(CC) -c $(CFLAGS) $(TARGET_CFLAGS) $(OPT_FLAGS) $(MIPSISET) $(DEF_INC_CFLAGS) -o $@ $< +ifeq ($(LIBGULTRA),1) + $(V)$(TOOLS_DIR)/patch_elf_32bit $@ +endif + +$(BUILD_DIR)/lib/ultra/%.o: lib/ultra/%.s + $(call print,Assembling:,$<,$@) + $(V)$(AS) $(ASFLAGS) $(ASOPT_FLAGS) $(MIPSISET) $(DEF_INC_CFLAGS) -o $@ $< + +ifeq ($(LIBULTRA_EXCLUSIVE),0) +# Exclusive file due to being in audio alongside using IDO and different optimization flags +$(BUILD_DIR)/lib/ultra/io/driverominit.o: lib/ultra/io/driverominit.c + $(call print,Compiling:,$<,$@) + $(V)$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/lib/ultra/io/$*.d $< + $(V)$(ULTRA_CC) -c $(ULTRA_CFLAGS) $(TARGET_CFLAGS) $(DEF_INC_CFLAGS) -mips2 -g -o $@ $< +endif + +# Link libultra +$(LIBULTRA_AR): $(ULTRA_O_FILES) + @$(PRINT) "$(GREEN)Linking libultra: $(BLUE)$@ $(NO_COL)\n" + $(V)$(AR) rcs -o $@ $(ULTRA_O_FILES) + $(V)$(TOOLS_DIR)/patch_elf_32bit $@ diff --git a/rename_sym.sh b/rename_sym.sh index 639105b6..8d4de36e 100755 --- a/rename_sym.sh +++ b/rename_sym.sh @@ -10,4 +10,4 @@ fi #echo "Replace $1 with $2?" #read -grep -rl "$1" text/**/*.{c,h} assets/**/*.c enhancements/*.patch lib/**/*.{c,h,s} asm/**/*.s bin/**/*.c data/*.c levels/**/*.{c,h} actors/**/*.{c,h} src/**/*.{c,h} include/**/*.{h,in} undefined_syms.txt | xargs sed -i "s/\b$1\b/$2/g" +grep -rl "$1" text/**/*.{c,h} assets/**/*.c enhancements/*.patch lib/**/*.{c,h,s} asm/**/*.s bin/**/*.c data/*.c levels/**/*.{c,h} actors/**/*.{c,h} src/**/*.{c,h} include/**/*.{h,in} | xargs sed -i "s/\b$1\b/$2/g" diff --git a/sm64.ld b/sm64.ld index c88b5c0e..a5364b84 100755 --- a/sm64.ld +++ b/sm64.ld @@ -11,6 +11,14 @@ OUTPUT_ARCH (mips) #define ADDR_OR_ALIGN(addr) ALIGN(0x1000) #endif +#if defined(VERSION_US) || defined(VERSION_JP) +#define AUDIO_DIR BUILD_DIR/src/audio/us_jp +#elif defined(VERSION_EU) +#define AUDIO_DIR BUILD_DIR/src/audio/eu +#elif defined(VERSION_SH) || defined(VERSION_CN) +#define AUDIO_DIR BUILD_DIR/src/audio/sh +#endif + #define BEGIN_SEG(name, addr) \ _##name##SegmentStart = ADDR(.name); \ _##name##SegmentRomStart = __romPos; \ @@ -101,13 +109,13 @@ SECTIONS { BUILD_DIR/src/buffers/buffers.o(.bss*); #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/port_sh.o(.bss*); + AUDIO_DIR/port.o(.bss*); #else - BUILD_DIR/src/audio/globals_start.o(.bss*); - BUILD_DIR/src/audio/synthesis.o(.bss*); - BUILD_DIR/src/audio/heap.o(.bss*); - BUILD_DIR/src/audio/load.o(.bss*); - BUILD_DIR/src/audio/data.o(.bss*); + AUDIO_DIR/globals_start.o(.bss*); + AUDIO_DIR/synthesis.o(.bss*); + AUDIO_DIR/heap.o(.bss*); + AUDIO_DIR/load.o(.bss*); + AUDIO_DIR/data.o(.bss*); #endif #ifdef VERSION_EU @@ -192,300 +200,36 @@ SECTIONS BUILD_DIR/src/game/hud.o(.text); BUILD_DIR/src/game/obj_behaviors.o(.text); BUILD_DIR/src/game/obj_behaviors_2.o(.text); + AUDIO_DIR/synthesis.o(.text); + AUDIO_DIR/heap.o(.text); + AUDIO_DIR/load.o(.text); #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/synthesis_sh.o(.text); -#else - BUILD_DIR/src/audio/synthesis.o(.text); + AUDIO_DIR/port.o(.text); #endif - BUILD_DIR/src/audio/heap.o(.text); - BUILD_DIR/src/audio/load.o(.text); + AUDIO_DIR/playback.o(.text); + AUDIO_DIR/effects.o(.text); + AUDIO_DIR/seqplayer.o(.text); +#ifndef LIBULTRA_EXCLUSIVE #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/load_sh.o(.text); - BUILD_DIR/src/audio/port_sh.o(.text); + BUILD_DIR/libultra.a:driverominit.o(.text); #endif - BUILD_DIR/src/audio/playback.o(.text); - BUILD_DIR/src/audio/effects.o(.text); - BUILD_DIR/src/audio/seqplayer.o(.text); -#if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/libultra.a:osDriveRomInit.o(.text); #endif BUILD_DIR/src/audio/external.o(.text); - BUILD_DIR/src/audio/port_eu.o(.text); +#ifdef VERSION_EU + AUDIO_DIR/port.o(.text); +#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#ifdef VERSION_CN - BUILD_DIR/libultra.a:osInitializeIQueWrapper.o(.text); - BUILD_DIR/libultra.a:osAiGetLength.o(.text); - BUILD_DIR/libultra.a:osAiSetFrequency.o(.text); - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.text); - BUILD_DIR/libultra.a:osInvalDCache.o(.text); - BUILD_DIR/libultra.a:osInvalICache.o(.text); - BUILD_DIR/libultra.a:osWritebackDCacheAll.o(.text); - BUILD_DIR/libultra.a:osContStartReadData.o(.text); - BUILD_DIR/libultra.a:osContInit.o(.text); - BUILD_DIR/libultra.a:osVirtualToPhysical.o(.text); - BUILD_DIR/libultra.a:sqrtf.o(.text); - BUILD_DIR/libultra.a:cosf.o(.text); - BUILD_DIR/libultra.a:guOrthoF.o(.text); - BUILD_DIR/libultra.a:guPerspectiveF.o(.text); - BUILD_DIR/libultra.a:sinf.o(.text); - BUILD_DIR/libultra.a:bcopy.o(.text); - BUILD_DIR/libultra.a:bzero.o(.text); - BUILD_DIR/libultra.a:llmuldiv.o(.text); - BUILD_DIR/libultra.a:llconv.o(.text); +#define SECTION text +#ifdef VERSION_JP +// JP has an additional 0x40 of weird padding space in text +#define JP_PADDING_TEXT #endif - BUILD_DIR/libultra.a:string.o(.text); - BUILD_DIR/libultra.a:_Printf.o(.text); -#ifdef VERSION_CN - BUILD_DIR/libultra.a:sprintf.o(.text); - BUILD_DIR/libultra.a:osSyncPrintf.o(.text); - BUILD_DIR/libultra.a:osCreateMesgQueue.o(.text); - BUILD_DIR/libultra.a:osRecvMesg.o(.text); - BUILD_DIR/libultra.a:osSendMesg.o(.text); - BUILD_DIR/libultra.a:osSetEventMesg.o(.text); - BUILD_DIR/libultra.a:osGetCount.o(.text); - BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.text); - BUILD_DIR/libultra.a:osSpTaskYield.o(.text); - BUILD_DIR/libultra.a:osSpTaskYielded.o(.text); - BUILD_DIR/libultra.a:__osSiRawStartDma.o(.text); - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.text); - BUILD_DIR/libultra.a:osCreateThread.o(.text); - BUILD_DIR/libultra.a:osSetThreadPri.o(.text); - BUILD_DIR/libultra.a:osStartThread.o(.text); - BUILD_DIR/libultra.a:__osDequeueThread.o(.text); - BUILD_DIR/libultra.a:__osGetCurrFaultedThread.o(.text); - BUILD_DIR/libultra.a:osGetTime.o(.text); - BUILD_DIR/libultra.a:osSetTime.o(.text); - BUILD_DIR/libultra.a:osSetTimer.o(.text); - BUILD_DIR/libultra.a:osTimer.o(.text); - BUILD_DIR/libultra.a:osMapTLB.o(.text); - BUILD_DIR/libultra.a:__osProbeTLB.o(.text); - BUILD_DIR/libultra.a:osUnmapTLBAll.o(.text); - BUILD_DIR/libultra.a:osCreateViManager.o(.text); - BUILD_DIR/libultra.a:osViSetEvent.o(.text); - BUILD_DIR/libultra.a:osViSetMode.o(.text); - BUILD_DIR/libultra.a:osViSetSpecialFeatures.o(.text); - BUILD_DIR/libultra.a:osViSwapBuffer.o(.text); - BUILD_DIR/libultra.a:__osViSwapContext.o(.text); - BUILD_DIR/libultra.a:osViBlack.o(.text); - BUILD_DIR/libultra.a:guMtxIdentF.o(.text); - BUILD_DIR/libultra.a:guMtxF2L.o(.text); - BUILD_DIR/libultra.a:guScale.o(.text); - BUILD_DIR/libultra.a:guTranslate.o(.text); - BUILD_DIR/libultra.a:guRotateF.o(.text); - BUILD_DIR/libultra.a:osEepromProbe.o(.text); - BUILD_DIR/libultra.a:osEepromLongWrite.o(.text); - BUILD_DIR/libultra.a:osEepromLongRead.o(.text); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.text); - BUILD_DIR/libultra.a:__osDisableInt.o(.text); - BUILD_DIR/libultra.a:__osRestoreInt.o(.text); - BUILD_DIR/libultra.a:osSetIntMask.o(.text); - BUILD_DIR/libultra.a:osCreatePiManager.o(.text); - BUILD_DIR/libultra.a:osEPiRawStartDma.o(.text); - BUILD_DIR/libultra.a:epidma.o(.text); - BUILD_DIR/libultra.a:osCartRomInit.o(.text); - BUILD_DIR/libultra.a:__osDevMgrMain.o(.text); - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.text); - BUILD_DIR/libultra.a:osPiStartDma.o(.text); - BUILD_DIR/libultra.a:iQueKernelCalls.o(.text); - BUILD_DIR/libultra.a:motor.o(.text); - BUILD_DIR/libultra.a:parameters.o(.text); - BUILD_DIR/libultra.a:osInitialize.o(.text); - BUILD_DIR/libultra.a:__osAiDeviceBusy.o(.text); - BUILD_DIR/libultra.a:osWritebackDCache.o(.text); - BUILD_DIR/libultra.a:_Litob.o(.text); - BUILD_DIR/libultra.a:_Ldtob.o(.text); - BUILD_DIR/libultra.a:osJamMesg.o(.text); - BUILD_DIR/libultra.a:__osGetCause.o(.text); - BUILD_DIR/libultra.a:__osGetSR.o(.text); - BUILD_DIR/libultra.a:__osSetFpcCsr.o(.text); - BUILD_DIR/libultra.a:__osSetSR.o(.text); - BUILD_DIR/libultra.a:__osSetWatchLo.o(.text); - BUILD_DIR/libultra.a:__osSetCompare.o(.text); - BUILD_DIR/libultra.a:__osSpDeviceBusy.o(.text); - BUILD_DIR/libultra.a:__osSpGetStatus.o(.text); - BUILD_DIR/libultra.a:__osSpSetStatus.o(.text); - BUILD_DIR/libultra.a:__osSpSetPc.o(.text); - BUILD_DIR/libultra.a:__osSpRawStartDma.o(.text); - BUILD_DIR/libultra.a:__osSiRawReadIo.o(.text); - BUILD_DIR/libultra.a:__osSiRawWriteIo.o(.text); - BUILD_DIR/libultra.a:osDestroyThread.o(.text); - BUILD_DIR/libultra.a:osGetThreadPri.o(.text); - BUILD_DIR/libultra.a:osYieldThread.o(.text); - BUILD_DIR/libultra.a:osMapTLBRdb.o(.text); - BUILD_DIR/libultra.a:__osViInit.o(.text); - BUILD_DIR/libultra.a:__osViGetCurrentContext.o(.text); - BUILD_DIR/libultra.a:guNormalize.o(.text); - BUILD_DIR/libultra.a:osEepromRead.o(.text); - BUILD_DIR/libultra.a:osEepromWrite.o(.text); - BUILD_DIR/libultra.a:__osSetGlobalIntMask.o(.text); - BUILD_DIR/libultra.a:__osResetGlobalIntMask.o(.text); - BUILD_DIR/libultra.a:osPiRawStartDma.o(.text); - BUILD_DIR/libultra.a:osPiGetCmdQueue.o(.text); - BUILD_DIR/libultra.a:osEPiRawReadIo.o(.text); - BUILD_DIR/libultra.a:osEPiRawWriteIo.o(.text); - BUILD_DIR/libultra.a:ldiv.o(.text); - BUILD_DIR/libultra.a:__osSiDeviceBusy.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:llmuldiv.o(.text); - BUILD_DIR/libultra.a:osInitialize.o(.text); - BUILD_DIR/libultra.a:osSetTime.o(.text); - BUILD_DIR/libultra.a:osGetTime.o(.text); - BUILD_DIR/libultra.a:osWritebackDCacheAll.o(.text); - BUILD_DIR/libultra.a:osViBlack.o(.text); - BUILD_DIR/libultra.a:osViSwapBuffer.o(.text); - BUILD_DIR/libultra.a:__osGetCurrFaultedThread.o(.text); - BUILD_DIR/libultra.a:osSetEventMesg.o(.text); - BUILD_DIR/libultra.a:osRecvMesg.o(.text); - BUILD_DIR/libultra.a:parameters.o(.text); - BUILD_DIR/libultra.a:osCreateMesgQueue.o(.text); - BUILD_DIR/libultra.a:osCreateThread.o(.text); - BUILD_DIR/libultra.a:osStartThread.o(.text); - BUILD_DIR/libultra.a:osMapTLB.o(.text); - BUILD_DIR/libultra.a:osUnmapTLBAll.o(.text); - BUILD_DIR/libultra.a:sprintf.o(.text); - BUILD_DIR/libultra.a:osViSetEvent.o(.text); - BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.text); - BUILD_DIR/libultra.a:osSpTaskYield.o(.text); - BUILD_DIR/libultra.a:osSendMesg.o(.text); - BUILD_DIR/libultra.a:osSpTaskYielded.o(.text); - BUILD_DIR/libultra.a:osCreateViManager.o(.text); - BUILD_DIR/libultra.a:osViSetMode.o(.text); - BUILD_DIR/libultra.a:osViSetSpecialFeatures.o(.text); - BUILD_DIR/libultra.a:osCreatePiManager.o(.text); - BUILD_DIR/libultra.a:osSetThreadPri.o(.text); - BUILD_DIR/libultra.a:sqrtf.o(.text); - BUILD_DIR/libultra.a:osContStartReadData.o(.text); - BUILD_DIR/libultra.a:osContInit.o(.text); - BUILD_DIR/libultra.a:osEepromProbe.o(.text); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:motor.o(.text); -#endif - BUILD_DIR/libultra.a:osInvalDCache.o(.text); - BUILD_DIR/libultra.a:osPiStartDma.o(.text); - BUILD_DIR/libultra.a:bzero.o(.text); - BUILD_DIR/libultra.a:osInvalICache.o(.text); - BUILD_DIR/libultra.a:osEepromLongRead.o(.text); - BUILD_DIR/libultra.a:osEepromLongWrite.o(.text); - BUILD_DIR/libultra.a:bcopy.o(.text); - BUILD_DIR/libultra.a:guOrthoF.o(.text); - BUILD_DIR/libultra.a:guPerspectiveF.o(.text); - BUILD_DIR/libultra.a:llconv.o(.text); - BUILD_DIR/libultra.a:cosf.o(.text); - BUILD_DIR/libultra.a:sinf.o(.text); - BUILD_DIR/libultra.a:guTranslateF.o(.text); - BUILD_DIR/libultra.a:guRotateF.o(.text); - BUILD_DIR/libultra.a:guScaleF.o(.text); - BUILD_DIR/libultra.a:osAiSetFrequency.o(.text); -#endif -#ifdef VERSION_SH - BUILD_DIR/libultra.a:osCartRomInit.o(.text); - BUILD_DIR/libultra.a:epidma.o(.text); -#endif -#ifdef VERSION_EU - BUILD_DIR/libultra.a:alBnkfNew.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:osAiGetLength.o(.text); - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.text); -#endif -#ifdef VERSION_SH - BUILD_DIR/libultra.a:osGetCount.o(.text); - BUILD_DIR/libultra.a:__osDisableInt.o(.text); - BUILD_DIR/libultra.a:__osRestoreInt.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:_Litob.o(.text); - BUILD_DIR/libultra.a:_Ldtob.o(.text); - BUILD_DIR/libultra.a:__osSetSR.o(.text); - BUILD_DIR/libultra.a:__osGetSR.o(.text); - BUILD_DIR/libultra.a:__osSetFpcCsr.o(.text); - BUILD_DIR/libultra.a:__osSiRawReadIo.o(.text); - BUILD_DIR/libultra.a:__osSiRawWriteIo.o(.text); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.text); - BUILD_DIR/libultra.a:osWritebackDCache.o(.text); - BUILD_DIR/libultra.a:osMapTLBRdb.o(.text); -#endif - BUILD_DIR/libultra.a:osPiRawReadIo.o(.text); - BUILD_DIR/libultra.a:__osSetHWintrRoutine.o(.text); -#ifdef VERSION_EU - BUILD_DIR/libultra.a:leointerrupt.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:osTimer.o(.text); -#endif -#ifdef VERSION_EU - BUILD_DIR/libultra.a:__osDisableInt.o(.text); - BUILD_DIR/libultra.a:__osRestoreInt.o(.text); - BUILD_DIR/libultra.a:osGetCount.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:__osViInit.o(.text); - BUILD_DIR/libultra.a:__osDequeueThread.o(.text); - BUILD_DIR/libultra.a:osVirtualToPhysical.o(.text); - BUILD_DIR/libultra.a:__osSpSetStatus.o(.text); - BUILD_DIR/libultra.a:__osSpSetPc.o(.text); - BUILD_DIR/libultra.a:__osSpRawStartDma.o(.text); - BUILD_DIR/libultra.a:__osSpDeviceBusy.o(.text); - BUILD_DIR/libultra.a:__osSpGetStatus.o(.text); - BUILD_DIR/libultra.a:osGetThreadPri.o(.text); - BUILD_DIR/libultra.a:__osViGetCurrentContext.o(.text); - BUILD_DIR/libultra.a:__osViSwapContext.o(.text); -#ifdef VERSION_SH - BUILD_DIR/libultra.a:osLeoDiskInit.o(.text); -#endif - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.text); - BUILD_DIR/libultra.a:osPiRawStartDma.o(.text); - BUILD_DIR/libultra.a:osEPiRawStartDma.o(.text); - BUILD_DIR/libultra.a:__osDevMgrMain.o(.text); - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.text); - BUILD_DIR/libultra.a:__osSiRawStartDma.o(.text); - BUILD_DIR/libultra.a:osSetTimer.o(.text); - BUILD_DIR/libultra.a:osEepromWrite.o(.text); -#endif -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:osPfsIsPlug.o(.text); - BUILD_DIR/libultra.a:crc.o(.text); - BUILD_DIR/libultra.a:contramwrite.o(.text); - BUILD_DIR/libultra.a:contramread.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:osJamMesg.o(.text); - BUILD_DIR/libultra.a:osPiGetCmdQueue.o(.text); - BUILD_DIR/libultra.a:osEepromRead.o(.text); - BUILD_DIR/libultra.a:guMtxF2L.o(.text); - BUILD_DIR/libultra.a:guNormalize.o(.text); - BUILD_DIR/libultra.a:__osAiDeviceBusy.o(.text); - BUILD_DIR/libultra.a:ldiv.o(.text); - BUILD_DIR/libultra.a:__osSiDeviceBusy.o(.text); -#endif -#ifdef VERSION_SH - BUILD_DIR/libultra.a:leointerrupt.o(.text); -#endif - BUILD_DIR/libultra.a:osSetIntMask.o(.text); -#ifndef VERSION_CN - BUILD_DIR/libultra.a:osDestroyThread.o(.text); -#endif -#ifdef VERSION_EU - BUILD_DIR/libultra.a:osLeoDiskInit.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:__osSetCompare.o(.text); - BUILD_DIR/libultra.a:__osProbeTLB.o(.text); - BUILD_DIR/libultra.a:__osResetGlobalIntMask.o(.text); - BUILD_DIR/libultra.a:osEPiRawWriteIo.o(.text); -#endif -#ifdef VERSION_SH - BUILD_DIR/libultra.a:osEPiRawReadIo.o(.text); - BUILD_DIR/libultra.a:__osSetGlobalIntMask.o(.text); -#endif -#ifndef VERSION_CN - BUILD_DIR/libultra.a:osYieldThread.o(.text); -#endif -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:pfsgetstatus.o(.text); + #include "lib/ultra/ld.inc" +#undef SECTION +#ifdef VERSION_JP +#undef JP_PADDING_TEXT #endif + #ifdef VERSION_CN BUILD_DIR/libgcc.a:_divdi3.o(.text); BUILD_DIR/libgcc.a:_moddi3.o(.text); @@ -500,129 +244,6 @@ SECTIONS BUILD_DIR/libgcc.a:_fixsfdi.o(.text); #endif BUILD_DIR/lib/rsp.o(.text); -#else - BUILD_DIR/src/game*.o(.text); - BUILD_DIR/src/audio*.o(.text); - BUILD_DIR/libultra.a:parameters.o(.text); - BUILD_DIR/libultra.a:osSetTime.o(.text); - BUILD_DIR/libultra.a:osMapTLB.o(.text); - BUILD_DIR/libultra.a:osUnmapTLBAll.o(.text); - BUILD_DIR/libultra.a:sprintf.o(.text); - BUILD_DIR/libultra.a:osCreateMesgQueue.o(.text); - BUILD_DIR/libultra.a:osSetEventMesg.o(.text); - BUILD_DIR/libultra.a:osViSetEvent.o(.text); - BUILD_DIR/libultra.a:osCreateThread.o(.text); - BUILD_DIR/libultra.a:osRecvMesg.o(.text); - BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.text); - BUILD_DIR/libultra.a:osSpTaskYield.o(.text); - BUILD_DIR/libultra.a:osSendMesg.o(.text); - BUILD_DIR/libultra.a:osSpTaskYielded.o(.text); - BUILD_DIR/libultra.a:osStartThread.o(.text); - BUILD_DIR/libultra.a:osWritebackDCacheAll.o(.text); - BUILD_DIR/libultra.a:osCreateViManager.o(.text); - BUILD_DIR/libultra.a:osViSetMode.o(.text); - BUILD_DIR/libultra.a:osViBlack.o(.text); - BUILD_DIR/libultra.a:osViSetSpecialFeatures.o(.text); - BUILD_DIR/libultra.a:osCreatePiManager.o(.text); - BUILD_DIR/libultra.a:osSetThreadPri.o(.text); - BUILD_DIR/libultra.a:osInitialize.o(.text); - BUILD_DIR/libultra.a:osViSwapBuffer.o(.text); - BUILD_DIR/libultra.a:sqrtf.o(.text); - BUILD_DIR/libultra.a:osContStartReadData.o(.text); - BUILD_DIR/libultra.a:osContInit.o(.text); - BUILD_DIR/libultra.a:osEepromProbe.o(.text); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:motor.o(.text); -#endif - BUILD_DIR/libultra.a:llmuldiv.o(.text); - BUILD_DIR/libultra.a:llmuldiv_gcc.o(.text); - BUILD_DIR/libultra.a:osInvalDCache.o(.text); - BUILD_DIR/libultra.a:osPiStartDma.o(.text); - BUILD_DIR/libultra.a:bzero.o(.text); - BUILD_DIR/libultra.a:osInvalICache.o(.text); - BUILD_DIR/libultra.a:osEepromLongRead.o(.text); - BUILD_DIR/libultra.a:osEepromLongWrite.o(.text); - BUILD_DIR/libultra.a:bcopy.o(.text); - BUILD_DIR/libultra.a:guOrthoF.o(.text); - BUILD_DIR/libultra.a:guPerspectiveF.o(.text); - BUILD_DIR/libultra.a:osGetTime.o(.text); - BUILD_DIR/libultra.a:llconv.o(.text); - BUILD_DIR/libultra.a:cosf.o(.text); - BUILD_DIR/libultra.a:sinf.o(.text); - BUILD_DIR/libultra.a:guTranslateF.o(.text); - BUILD_DIR/libultra.a:guRotateF.o(.text); - BUILD_DIR/libultra.a:guScaleF.o(.text); - BUILD_DIR/libultra.a:osAiSetFrequency.o(.text); - BUILD_DIR/libultra.a:alBnkfNew.o(.text); - BUILD_DIR/libultra.a:osWritebackDCache.o(.text); - BUILD_DIR/libultra.a:osAiGetLength.o(.text); - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.text); - BUILD_DIR/libultra.a:osTimer.o(.text); - BUILD_DIR/libultra.a:_Printf.o(.text); - BUILD_DIR/libultra.a:string.o(.text); - BUILD_DIR/libultra.a:__osDequeueThread.o(.text); - BUILD_DIR/libultra.a:__osDisableInt.o(.text); - BUILD_DIR/libultra.a:__osRestoreInt.o(.text); - BUILD_DIR/libultra.a:__osViInit.o(.text); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.text); - BUILD_DIR/libultra.a:osVirtualToPhysical.o(.text); - BUILD_DIR/libultra.a:__osSpSetStatus.o(.text); - BUILD_DIR/libultra.a:__osSpSetPc.o(.text); - BUILD_DIR/libultra.a:__osSpRawStartDma.o(.text); - BUILD_DIR/libultra.a:__osSpDeviceBusy.o(.text); - BUILD_DIR/libultra.a:__osSpGetStatus.o(.text); - BUILD_DIR/libultra.a:osGetThreadPri.o(.text); - BUILD_DIR/libultra.a:__osViGetCurrentContext.o(.text); - BUILD_DIR/libultra.a:__osViSwapContext.o(.text); - BUILD_DIR/libultra.a:osGetCount.o(.text); - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.text); - BUILD_DIR/libultra.a:osPiRawStartDma.o(.text); - BUILD_DIR/libultra.a:__osDevMgrMain.o(.text); - BUILD_DIR/libultra.a:__osSetSR.o(.text); - BUILD_DIR/libultra.a:__osGetSR.o(.text); - BUILD_DIR/libultra.a:__osSetFpcCsr.o(.text); - BUILD_DIR/libultra.a:__osSiRawReadIo.o(.text); - BUILD_DIR/libultra.a:__osSiRawWriteIo.o(.text); - BUILD_DIR/libultra.a:osMapTLBRdb.o(.text); - BUILD_DIR/libultra.a:osPiRawReadIo.o(.text); -#ifdef VERSION_JP - . += 0x40; -#endif - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.text); - BUILD_DIR/libultra.a:__osSiRawStartDma.o(.text); - BUILD_DIR/libultra.a:osSetTimer.o(.text); - BUILD_DIR/libultra.a:osEepromWrite.o(.text); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:osPfsIsPlug.o(.text); - BUILD_DIR/libultra.a:crc.o(.text); - BUILD_DIR/libultra.a:contramwrite.o(.text); - BUILD_DIR/libultra.a:contramread.o(.text); -#endif - BUILD_DIR/libultra.a:osJamMesg.o(.text); - BUILD_DIR/libultra.a:osPiGetCmdQueue.o(.text); - BUILD_DIR/libultra.a:osEepromRead.o(.text); - BUILD_DIR/libultra.a:guMtxF2L.o(.text); - BUILD_DIR/libultra.a:guMtxIdentF.o(.text); - BUILD_DIR/libultra.a:guNormalize.o(.text); - BUILD_DIR/libultra.a:__osAiDeviceBusy.o(.text); - BUILD_DIR/libultra.a:__osSetCompare.o(.text); - BUILD_DIR/libultra.a:_Litob.o(.text); - BUILD_DIR/libultra.a:_Ldtob.o(.text); - BUILD_DIR/libultra.a:kdebugserver.o(.text); - BUILD_DIR/libultra.a:__osSyncPutChars.o(.text); - BUILD_DIR/libultra.a:osSetIntMask.o(.text); - BUILD_DIR/libultra.a:osDestroyThread.o(.text); - BUILD_DIR/libultra.a:__osProbeTLB.o(.text); - BUILD_DIR/libultra.a:__osSiDeviceBusy.o(.text); - BUILD_DIR/libultra.a:ldiv.o(.text); - BUILD_DIR/libultra.a:__osGetCause.o(.text); - BUILD_DIR/libultra.a:__osAtomicDec.o(.text); - BUILD_DIR/libultra.a:guLookAtRef.o(.text); /* Fast3DEX2 only */ -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:pfsgetstatus.o(.text); -#endif - BUILD_DIR/lib/rsp.o(.text); -#endif /* data */ BUILD_DIR/src/game/crash_screen.o(.data*); @@ -673,93 +294,32 @@ SECTIONS /* wildcard doesn't match on EU due to files being moved to engine/ */ BUILD_DIR/src/game*.o(.data*); #endif -#if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/synthesis_sh.o(.data*); -#else - BUILD_DIR/src/audio/synthesis.o(.data*); + AUDIO_DIR/synthesis.o(.data*); + AUDIO_DIR/heap.o(.data*); +#if !defined(VERSION_SH) && !defined(VERSION_CN) + AUDIO_DIR/load.o(.data*); #endif - BUILD_DIR/src/audio/heap.o(.data*); - BUILD_DIR/src/audio/load.o(.data*); - BUILD_DIR/src/audio/playback.o(.data*); - BUILD_DIR/src/audio/effects.o(.data*); - BUILD_DIR/src/audio/seqplayer.o(.data*); + AUDIO_DIR/playback.o(.data*); + AUDIO_DIR/effects.o(.data*); + AUDIO_DIR/seqplayer.o(.data*); #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/data.o(.data*); - BUILD_DIR/src/audio/shindou_debug_prints.o(.data*); - BUILD_DIR/src/audio/port_sh.o(.data*); + AUDIO_DIR/data.o(.data*); + AUDIO_DIR/debug_prints.o(.data*); + AUDIO_DIR/port.o(.data*); +#endif BUILD_DIR/src/audio/external.o(.data*); - BUILD_DIR/src/audio/audio_session_presets_sh.o(.data*); +#if defined(VERSION_SH) || defined(VERSION_CN) + AUDIO_DIR/audio_session_presets.o(.data*); #else - BUILD_DIR/src/audio/external.o(.data*); - BUILD_DIR/src/audio/port_eu.o(.data*); - BUILD_DIR/src/audio/data.o(.data*); +#ifdef VERSION_EU + AUDIO_DIR/port.o(.data*); +#endif + AUDIO_DIR/data.o(.data*); #endif -#ifdef VERSION_CN - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.data*); - BUILD_DIR/libultra.a:osContInit.o(.data*); - BUILD_DIR/libultra.a:_Printf.o(.data*); - BUILD_DIR/libultra.a:osSetEventMesg.o(.data*); - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.data*); - BUILD_DIR/libultra.a:__osDequeueThread.o(.data*); - BUILD_DIR/libultra.a:osTimer.o(.data*); - BUILD_DIR/libultra.a:osCreateViManager.o(.data*); - BUILD_DIR/libultra.a:osViTable.o(.data*); - BUILD_DIR/libultra.a:guRotateF.o(.data*); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.data*); - BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); - BUILD_DIR/libultra.a:osCartRomInit.o(.data*); - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.data*); - BUILD_DIR/libultra.a:osInitialize.o(.data*); - BUILD_DIR/libultra.a:_Litob.o(.data*); - BUILD_DIR/libultra.a:__osViInit.o(.data*); - BUILD_DIR/libultra.a:osViData.o(.data*); -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/libultra.a:_Printf.o(.data*); - BUILD_DIR/libultra.a:osInitialize.o(.data*); - BUILD_DIR/libultra.a:osCreateViManager.o(.data*); - BUILD_DIR/libultra.a:osViTable.o(.data*); - BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); - BUILD_DIR/libultra.a:osContInit.o(.data*); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:motor.o(.data*); -#endif - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.data*); - BUILD_DIR/libultra.a:_Litob.o(.data*); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.data*); - BUILD_DIR/libultra.a:osTimer.o(.data*); - BUILD_DIR/libultra.a:__osViInit.o(.data*); - BUILD_DIR/libultra.a:__osDequeueThread.o(.data*); - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.data*); - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.data*); - BUILD_DIR/libultra.a:osViData.o(.data*); -#else - BUILD_DIR/libultra.a:osViTable.o(.data*); - BUILD_DIR/libultra.a:osCreateViManager.o(.data*); - BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); - BUILD_DIR/libultra.a:osInitialize.o(.data*); - BUILD_DIR/libultra.a:osContInit.o(.data*); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:motor.o(.data*); -#endif - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.data*); - BUILD_DIR/libultra.a:osTimer.o(.data*); - BUILD_DIR/libultra.a:_Printf.o(.data*); - BUILD_DIR/libultra.a:__osDequeueThread.o(.data*); - BUILD_DIR/libultra.a:__osViInit.o(.data*); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.data*); - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.data*); - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.data*); - BUILD_DIR/libultra.a:_Litob.o(.data*); - BUILD_DIR/libultra.a:_Ldtob.o(.data*); - BUILD_DIR/libultra.a:osViData.o(.data*); - BUILD_DIR/libultra.a:kdebugserver.o(.data*); - BUILD_DIR/libultra.a:__osSyncPutChars.o(.data*); - BUILD_DIR/libultra.a:guRotateF.o(.data*); - BUILD_DIR/libultra.a:*.o(.data*); -#endif +#define SECTION data* + #include "lib/ultra/ld.inc" +#undef SECTION /* rodata */ BUILD_DIR/src/game/crash_screen.o(.rodata*); @@ -792,8 +352,6 @@ SECTIONS BUILD_DIR/src/game/object_collision.o(.rodata*); BUILD_DIR/src/game/spawn_object.o(.rodata*); #endif - BUILD_DIR/libultra.a:__osDisableInt.o(.text); - BUILD_DIR/libultra.a:__osRestoreInt.o(.text); BUILD_DIR/src/game/spawn_sound.o(.rodata*); BUILD_DIR/src/game/debug.o(.rodata*); BUILD_DIR/src/game/screen_transition.o(.rodata*); @@ -813,58 +371,24 @@ SECTIONS #if defined(VERSION_JP) || defined(VERSION_US) BUILD_DIR/src/game*.o(.rodata*); #endif + AUDIO_DIR/synthesis.o(.rodata*); + AUDIO_DIR/heap.o(.rodata*); + AUDIO_DIR/load.o(.rodata*); #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/synthesis_sh.o(.rodata*); - BUILD_DIR/src/audio/heap.o(.rodata*); - BUILD_DIR/src/audio/load_sh.o(.rodata*); - BUILD_DIR/src/audio/port_sh.o(.rodata*); -#else - BUILD_DIR/src/audio/synthesis.o(.rodata*); - BUILD_DIR/src/audio/heap.o(.rodata*); - BUILD_DIR/src/audio/load.o(.rodata*); + AUDIO_DIR/port.o(.rodata*); #endif - BUILD_DIR/src/audio/playback.o(.rodata*); - BUILD_DIR/src/audio/effects.o(.rodata*); - BUILD_DIR/src/audio/seqplayer.o(.rodata*); + AUDIO_DIR/playback.o(.rodata*); + AUDIO_DIR/effects.o(.rodata*); + AUDIO_DIR/seqplayer.o(.rodata*); BUILD_DIR/src/audio/external.o(.rodata*); - BUILD_DIR/src/audio/port_eu.o(.rodata*); - BUILD_DIR/src/audio*.o(.rodata*); +#ifdef VERSION_EU + AUDIO_DIR/port.o(.rodata*); +#endif + AUDIO_DIR*.o(.rodata*); -#if defined(VERSION_EU) || defined(VERSION_SH) - BUILD_DIR/libultra.a:_Printf.o(.rodata*); -#endif - -#ifndef VERSION_CN - BUILD_DIR/libultra.a:guPerspectiveF.o(.rodata*); -#endif - BUILD_DIR/libultra.a:llconv.o(.rodata*); - BUILD_DIR/libultra.a:cosf.o(.rodata*); -#ifdef VERSION_CN - BUILD_DIR/libultra.a:guPerspectiveF.o(.rodata*); -#endif - BUILD_DIR/libultra.a:sinf.o(.rodata*); - BUILD_DIR/libultra.a:guRotateF.o(.rodata*); - -#if defined(VERSION_EU) || defined(VERSION_SH) - BUILD_DIR/libultra.a:_Litob.o(.rodata*); - BUILD_DIR/libultra.a:_Ldtob.o(.rodata*); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.rodata*); - BUILD_DIR/libultra.a:__osDevMgrMain.o(.rodata*); - BUILD_DIR/libultra.a:NaN.o(.rodata*); -#else - BUILD_DIR/libultra.a:_Printf.o(.rodata*); - BUILD_DIR/libultra.a:__osExceptionPreamble.o(.rodata*); -#ifdef VERSION_CN - BUILD_DIR/libultra.a:osSetIntMask.o(.rodata*); - BUILD_DIR/libultra.a:__osDevMgrMain.o(.rodata*); -#endif - BUILD_DIR/libultra.a:NaN.o(.rodata*); - BUILD_DIR/libultra.a:_Litob.o(.rodata*); - BUILD_DIR/libultra.a:_Ldtob.o(.rodata*); -#endif - - BUILD_DIR/libultra.a:osSetIntMask.o(.rodata*); - BUILD_DIR/libultra.a:guLookAtRef.o(.rodata*); /* Fast3DEX2 only */ +#define SECTION rodata* + #include "lib/ultra/ld.inc" +#undef SECTION #ifdef VERSION_CN BUILD_DIR/libgcc.a:_divdi3.o(.rodata*); @@ -878,13 +402,10 @@ SECTIONS BUILD_DIR/libgcc.a:_fixdfdi.o(.rodata*); BUILD_DIR/libgcc.a:_fixunssfdi.o(.rodata*); BUILD_DIR/libgcc.a:_fixsfdi.o(.rodata*); -#endif -#ifndef VERSION_EU - BUILD_DIR/libultra.a:*.o(.rodata*); #endif /* audio blobs, should really be moved into a separate file */ #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/load_sh.o(.data*); + AUDIO_DIR/load.o(.data*); #endif BUILD_DIR/lib/rsp.o(.rodata*); } @@ -937,84 +458,26 @@ SECTIONS #endif BUILD_DIR/src/audio/external.o(.bss*); #ifdef VERSION_EU - BUILD_DIR/src/audio/port_eu.o(.bss*); + AUDIO_DIR/port.o(.bss*); #endif #if defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/src/audio/globals_start.o(.bss*); - BUILD_DIR/src/audio/synthesis_sh.o(.bss*); - BUILD_DIR/src/audio/heap.o(.bss*); - BUILD_DIR/src/audio/load_sh.o(.bss*); - BUILD_DIR/src/audio/data.o(.bss*); + AUDIO_DIR/globals_start.o(.bss*); + AUDIO_DIR/synthesis.o(.bss*); + AUDIO_DIR/heap.o(.bss*); + AUDIO_DIR/load.o(.bss*); + AUDIO_DIR/data.o(.bss*); #endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - BUILD_DIR/libultra.a:osInitialize.o(.bss*); - BUILD_DIR/libultra.a:osSetEventMesg.o(.bss*); - BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.bss*); -#ifdef VERSION_CN - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); -#endif - BUILD_DIR/libultra.a:osCreateViManager.o(.bss*); - BUILD_DIR/libultra.a:osCreatePiManager.o(.bss*); - BUILD_DIR/libultra.a:osContStartReadData.o(.bss*); - BUILD_DIR/libultra.a:osContInit.o(.bss*); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:motor.o(.bss*); -#endif - BUILD_DIR/libultra.a:guRotateF.o(.bss*); +#define SECTION bss* #ifdef VERSION_SH - BUILD_DIR/libultra.a:osCartRomInit.o(.bss*); +// osPfsIsPlug bss section is located slightly different in Shindou. +#define SH_PFS_BSS #endif -#ifdef VERSION_EU - BUILD_DIR/libultra.a:leointerrupt.o(.bss*); -#endif - BUILD_DIR/libultra.a:osTimer.o(.bss*); + #include "lib/ultra/ld.inc" +#undef SECTION #ifdef VERSION_SH - BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*); +#undef SH_PFS_BSS #endif - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.bss*); -#ifndef VERSION_CN - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); -#endif -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:osPfsIsPlug.o(.bss*); -#endif - BUILD_DIR/libultra.a:osEepromWrite.o(.bss*); - BUILD_DIR/libultra.a:kdebugserver.o(.bss*); -#ifdef VERSION_SH - BUILD_DIR/libultra.a:leointerrupt.o(.bss*); -#endif -#ifdef VERSION_EU - BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*); -#endif - BUILD_DIR/libultra.a:_Printf.o(.bss*); - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.bss*); - BUILD_DIR/libultra.a:__osSetHWintrRoutine.o(.bss*); -#else - BUILD_DIR/libultra.a:osSetEventMesg.o(.bss*); - BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.bss*); - BUILD_DIR/libultra.a:osCreateViManager.o(.bss*); - BUILD_DIR/libultra.a:osCreatePiManager.o(.bss*); - BUILD_DIR/libultra.a:osInitialize.o(.bss*); - BUILD_DIR/libultra.a:osContStartReadData.o(.bss*); - BUILD_DIR/libultra.a:osContInit.o(.bss*); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:motor.o(.bss*); -#endif - BUILD_DIR/libultra.a:guRotateF.o(.bss*); - BUILD_DIR/libultra.a:osTimer.o(.bss*); - BUILD_DIR/libultra.a:_Printf.o(.bss*); - BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.bss*); - BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); -#if ENABLE_RUMBLE - BUILD_DIR/libultra.a:osPfsIsPlug.o(.bss*); -#endif - BUILD_DIR/libultra.a:osEepromWrite.o(.bss*); - BUILD_DIR/libultra.a:kdebugserver_stack.o(.bss*); - BUILD_DIR/libultra.a:kdebugserver.o(.bss*); -#endif - - BUILD_DIR/libultra.a:*.o(.bss*); BUILD_DIR/src/game/cn_common_syms_2.o(.bss*); @@ -1023,11 +486,17 @@ SECTIONS END_NOLOAD(main) #ifdef VERSION_CN - // Hack for CN to make asm/entry.s match, since we aren't using + // Hack for CN to make these asm files to match, since we aren't using // the original assembler and so can't get lui/ori from la pseudo + + // asm/entry.s CREATE_LO_HI_PAIR(_mainSegmentNoloadStart, ADDR (.main.noload)) CREATE_LO_HI_PAIR(gIdleThreadStack, gIdleThreadStack) CREATE_LO_HI_PAIR(main_func, main_func) + + // asm/boot.s + SP_DMEM_CN_UNK0 = 0x0400049C; + SP_DMEM_CN_UNK1 = 0x0400074C; #endif CREATE_LO_HI_PAIR(_mainSegmentNoloadSize, SIZEOF (.main.noload)) @@ -1347,5 +816,5 @@ SECTIONS ASSERT((_goddardSegmentNoloadEnd <= SEG_POOL_END), "Error: menu segment extended past pool end") ASSERT((_mainSegmentNoloadEnd <= _engineSegmentStart), "Error: main segment extended into engine.") ASSERT((_engineSegmentNoloadEnd <= _framebuffersSegmentNoloadStart), "Error: engine segment extended into framebuffers.") - ASSERT((_framebuffersSegmentNoloadEnd <= RDRAM_END), "Error: framebuffers segment extended past RDRAM end") + ASSERT((_framebuffersSegmentNoloadEnd <= SEG_RAM_END), "Error: framebuffers segment extended past RDRAM end") } diff --git a/src/audio/copt/seq_channel_layer_process_script_copt.inc.c b/src/audio/copt/seq_channel_layer_process_script_copt.inc.c deleted file mode 100644 index ab8da804..00000000 --- a/src/audio/copt/seq_channel_layer_process_script_copt.inc.c +++ /dev/null @@ -1,500 +0,0 @@ -//! Copt inlining for US/JP. Here be dragons -// This version is basically identical to EU - -#include -#include - -#include "audio/heap.h" -#include "audio/data.h" -#include "audio/load.h" -#include "audio/seqplayer.h" -#include "audio/external.h" -#include "audio/effects.h" - -#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) -#define PORTAMENTO_MODE(x) ((x).mode & ~0x80) -#define PORTAMENTO_MODE_1 1 -#define PORTAMENTO_MODE_2 2 -#define PORTAMENTO_MODE_3 3 -#define PORTAMENTO_MODE_4 4 -#define PORTAMENTO_MODE_5 5 - -#define COPT 0 -#if COPT -#define M64_READ_U8(state, dst) \ - dst = m64_read_u8(state); -#else -#define M64_READ_U8(state, dst) \ -{ \ - u8 * _ptr_pc; \ - u8 _pc; \ - _ptr_pc = (*state).pc; \ - ((*state).pc)++; \ - _pc = *_ptr_pc; \ - dst = _pc; \ -} -#endif - - -#if COPT -#define M64_READ_S16(state, dst) \ - dst = m64_read_s16(state); -#else -#define M64_READ_S16(state, dst) \ -{ \ - s16 _ret; \ - _ret = *(*state).pc << 8; \ - ((*state).pc)++; \ - _ret = *(*state).pc | _ret; \ - ((*state).pc)++; \ - dst = _ret; \ -} -#endif -#if COPT -#define M64_READ_COMPRESSED_U16(state, dst) \ - dst = m64_read_compressed_u16(state); -#else -#define M64_READ_COMPRESSED_U16(state, dst) \ -{ \ - u16 ret = *(state->pc++); \ - if (ret & 0x80) { \ - ret = (ret << 8) & 0x7f00; \ - ret = *(state->pc++) | ret; \ - } \ - dst = ret; \ -} -#endif - -#if COPT -#define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ - dst = get_instrument(seqChannel, instId, _instOut, _adsr); -#else -#define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ -{ \ -struct AdsrSettings *adsr = _adsr; \ -struct Instrument **instOut = _instOut;\ - u8 _instId = instId; \ - struct Instrument *inst; \ - UNUSED u32 pad; \ - /* copt inlines instId here */ \ - if (instId >= gCtlEntries[(*seqChannel).bankId].numInstruments) { \ - _instId = gCtlEntries[(*seqChannel).bankId].numInstruments; \ - if (_instId == 0) { \ - dst = 0; \ - goto ret ## l; \ - } \ - _instId--; \ - } \ - inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \ - if (inst == NULL) { \ - while (_instId != 0xff) { \ - inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \ - if (inst != NULL) { \ - goto gi ## l; \ - } \ - _instId--; \ - } \ - gi ## l:; \ - } \ - if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst \ - && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start \ - + gBankLoadedPool.persistent.pool.size)) \ - || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst \ - && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start \ - + gBankLoadedPool.temporary.pool.size))) { \ - (*adsr).envelope = (*inst).envelope; \ - (*adsr).releaseRate = (*inst).releaseRate; \ - *instOut = inst; \ - _instId++; \ - goto ret ## l; \ - } \ - gAudioErrorFlags = _instId + 0x20000; \ - *instOut = NULL; \ - ret ## l: ; \ -} -#endif - -void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { - struct SequencePlayer *seqPlayer; // sp5C, t4 - struct SequenceChannel *seqChannel; // sp58, t5 - struct M64ScriptState *state; - struct Portamento *portamento; - struct AudioBankSound *sound; - struct Instrument *instrument; - struct Drum *drum; - s32 temp_a0_5; - u8 sameSound; - u8 cmd; // a0 sp3E, EU s2 - u8 cmdSemitone; // sp3D, t0 - u16 sp3A; // t2, a0, a1 - f32 tuning; // f0 - s32 vel; // sp30, t3 - s32 usedSemitone; // a1 - f32 freqScale; // sp28, f0 - f32 sp24; - f32 temp_f12; - f32 temp_f2; - -//! Copt: manually inline these functions in the scope of this routine -#ifdef __sgi -#pragma inline routine(m64_read_u8) -#pragma inline routine(m64_read_compressed_u16) -#pragma inline routine(m64_read_s16) -#pragma inline routine(get_instrument) -#endif - - sameSound = TRUE; - if ((*layer).enabled == FALSE) { - return; - } - - if ((*layer).delay > 1) { - (*layer).delay--; - if (!layer->stopSomething && layer->delay <= layer->duration) { - seq_channel_layer_note_decay(layer); - layer->stopSomething = TRUE; - } - return; - } - - if (!layer->continuousNotes) { - seq_channel_layer_note_decay(layer); - } - - if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 || - PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) { - layer->portamento.mode = 0; - } - - seqChannel = (*layer).seqChannel; - seqPlayer = (*seqChannel).seqPlayer; - for (;;) { - state = &layer->scriptState; - //M64_READ_U8(state, cmd); - { - u8 *_ptr_pc; - _ptr_pc = (*state).pc++; - cmd = *_ptr_pc; - } - - if (cmd <= 0xc0) { - break; - } - - switch (cmd) { - case 0xff: // layer_end; function return or end of script - if (state->depth == 0) { - // N.B. this function call is *not* inlined even though it's - // within the same file, unlike in the rest of this function. - seq_channel_layer_disable(layer); - return; - } - state->depth--, state->pc = state->stack[state->depth]; - break; - - case 0xfc: // layer_call - M64_READ_S16(state, sp3A); - state->depth++, state->stack[state->depth - 1] = state->pc; - state->pc = seqPlayer->seqData + sp3A; - break; - - case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) - M64_READ_U8(state, state->remLoopIters[state->depth]); - state->depth++, state->stack[state->depth - 1] = state->pc; - break; - - case 0xf7: // layer_loopend - if (--state->remLoopIters[state->depth - 1] != 0) { - state->pc = state->stack[state->depth - 1]; - } else { - state->depth--; - } - break; - - case 0xfb: // layer_jump - M64_READ_S16(state, sp3A); - state->pc = seqPlayer->seqData + sp3A; - break; - - case 0xc1: // layer_setshortnotevelocity - case 0xca: // layer_setpan - temp_a0_5 = *(state->pc++); - if (cmd == 0xc1) { - layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5); - } else { - layer->pan = (f32) temp_a0_5 / US_FLOAT(128.0); - } - break; - - case 0xc2: // layer_transpose; set transposition in semitones - case 0xc9: // layer_setshortnoteduration - temp_a0_5 = *(state->pc++); - if (cmd == 0xc9) { - layer->noteDuration = temp_a0_5; - } else { - layer->transposition = temp_a0_5; - } - break; - - case 0xc4: // layer_somethingon - case 0xc5: // layer_somethingoff - //! copt needs a ternary: - //layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE; - { - u8 setting; - if (cmd == 0xc4) { - setting = TRUE; - } else { - setting = FALSE; - } - layer->continuousNotes = setting; - seq_channel_layer_note_decay(layer); - } - break; - - case 0xc3: // layer_setshortnotedefaultplaypercentage - M64_READ_COMPRESSED_U16(state, sp3A); - layer->shortNoteDefaultPlayPercentage = sp3A; - break; - - case 0xc6: // layer_setinstr - M64_READ_U8(state, cmdSemitone); - - if (cmdSemitone < 127) { - GET_INSTRUMENT(seqChannel, cmdSemitone, &(*layer).instrument, &(*layer).adsr, cmdSemitone, 1); - } - break; - - case 0xc7: // layer_portamento - M64_READ_U8(state, (*layer).portamento.mode); - M64_READ_U8(state, cmdSemitone); - - cmdSemitone = cmdSemitone + (*seqChannel).transposition; - cmdSemitone += (*layer).transposition; - cmdSemitone += (*seqPlayer).transposition; - - if (cmdSemitone >= 0x80) { - cmdSemitone = 0; - } - layer->portamentoTargetNote = cmdSemitone; - - // If special, the next param is u8 instead of var - if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) { - layer->portamentoTime = *((state)->pc++); - break; - } - - M64_READ_COMPRESSED_U16(state, sp3A); - layer->portamentoTime = sp3A; - break; - - case 0xc8: // layer_disableportamento - layer->portamento.mode = 0; - break; - - default: - switch (cmd & 0xf0) { - case 0xd0: // layer_setshortnotevelocityfromtable - sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xf]; - (*layer).velocitySquare = (f32)(sp3A * sp3A); - break; - case 0xe0: // layer_setshortnotedurationfromtable - (*layer).noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf]; - break; - } - } - } - - if (cmd == 0xc0) { // layer_delay - M64_READ_COMPRESSED_U16(state, layer->delay); - layer->stopSomething = TRUE; - } else { - layer->stopSomething = FALSE; - - if (seqChannel->largeNotes == TRUE) { - switch (cmd & 0xc0) { - case 0x00: // layer_note0 (play percentage, velocity, duration) - M64_READ_COMPRESSED_U16(state, sp3A); - vel = *((*state).pc++); - layer->noteDuration = *((*state).pc++); - layer->playPercentage = sp3A; - goto l1090; - - case 0x40: // layer_note1 (play percentage, velocity) - M64_READ_COMPRESSED_U16(state, sp3A); - vel = *((*state).pc++); - layer->noteDuration = 0; - layer->playPercentage = sp3A; - goto l1090; - - case 0x80: // layer_note2 (velocity, duration; uses last play percentage) - sp3A = layer->playPercentage; - vel = *((*state).pc++); - layer->noteDuration = *((*state).pc++); - goto l1090; - } -l1090: - cmdSemitone = cmd - (cmd & 0xc0); - layer->velocitySquare = vel * vel; - } else { - switch (cmd & 0xc0) { - case 0x00: // play note, type 0 (play percentage) - M64_READ_COMPRESSED_U16(state, sp3A); - layer->playPercentage = sp3A; - goto l1138; - - case 0x40: // play note, type 1 (uses default play percentage) - sp3A = layer->shortNoteDefaultPlayPercentage; - goto l1138; - - case 0x80: // play note, type 2 (uses last play percentage) - sp3A = layer->playPercentage; - goto l1138; - } -l1138: - - cmdSemitone = cmd - (cmd & 0xc0); - } - - layer->delay = sp3A; - layer->duration = layer->noteDuration * sp3A / 256; - if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0) - || seqChannel->stopSomething2 - || !seqChannel->hasInstrument - ) { - layer->stopSomething = TRUE; - } else { - if (seqChannel->instOrWave == 0) { // drum - cmdSemitone += (*seqChannel).transposition + (*layer).transposition; - if (cmdSemitone >= gCtlEntries[seqChannel->bankId].numDrums) { - cmdSemitone = gCtlEntries[seqChannel->bankId].numDrums; - if (cmdSemitone == 0) { - // this goto looks a bit like a function return... - layer->stopSomething = TRUE; - goto skip; - } - - cmdSemitone--; - } - - drum = gCtlEntries[seqChannel->bankId].drums[cmdSemitone]; - if (drum == NULL) { - layer->stopSomething = TRUE; - } else { - layer->adsr.envelope = drum->envelope; - layer->adsr.releaseRate = drum->releaseRate; - layer->pan = FLOAT_CAST(drum->pan) / US_FLOAT(128.0); - layer->sound = &drum->sound; - layer->freqScale = layer->sound->tuning; - } - - skip:; - } else { // instrument - cmdSemitone += (*seqPlayer).transposition + (*seqChannel).transposition + (*layer).transposition; - if (cmdSemitone >= 0x80) { - layer->stopSomething = TRUE; - } else { - instrument = layer->instrument; - if (instrument == NULL) { - instrument = seqChannel->instrument; - } - - if (layer->portamento.mode != 0) { - //! copt needs a ternary: - //usedSemitone = (layer->portamentoTargetNote < cmdSemitone) ? cmdSemitone : layer->portamentoTargetNote; - if (layer->portamentoTargetNote < cmdSemitone) { - usedSemitone = cmdSemitone; - } else { - usedSemitone = layer->portamentoTargetNote; - } - - if (instrument != NULL) { - sound = (u8) usedSemitone < instrument->normalRangeLo ? &instrument->lowNotesSound - : (u8) usedSemitone <= instrument->normalRangeHi ? - &instrument->normalNotesSound : &instrument->highNotesSound; - - sameSound = (sound == (*layer).sound); - layer->sound = sound; - tuning = (*sound).tuning; - } else { - layer->sound = NULL; - tuning = 1.0f; - } - - temp_f2 = gNoteFrequencies[cmdSemitone] * tuning; - temp_f12 = gNoteFrequencies[layer->portamentoTargetNote] * tuning; - - portamento = &layer->portamento; - switch (PORTAMENTO_MODE(layer->portamento)) { - case PORTAMENTO_MODE_1: - case PORTAMENTO_MODE_3: - case PORTAMENTO_MODE_5: - sp24 = temp_f2; - freqScale = temp_f12; - goto l13cc; - - case PORTAMENTO_MODE_2: - case PORTAMENTO_MODE_4: - freqScale = temp_f2; - sp24 = temp_f12; - goto l13cc; - } -l13cc: - portamento->extent = sp24 / freqScale - US_FLOAT(1.0); - if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) { - portamento->speed = US_FLOAT(32512.0) * FLOAT_CAST((*seqPlayer).tempo) - / ((f32)(*layer).delay * (f32) gTempoInternalToExternal - * FLOAT_CAST((*layer).portamentoTime)); - } else { - portamento->speed = US_FLOAT(127.0) / FLOAT_CAST((*layer).portamentoTime); - } - portamento->cur = 0.0f; - layer->freqScale = freqScale; - if (PORTAMENTO_MODE((*layer).portamento) == PORTAMENTO_MODE_5) { - layer->portamentoTargetNote = cmdSemitone; - } - } else if (instrument != NULL) { - sound = cmdSemitone < instrument->normalRangeLo ? - &instrument->lowNotesSound : cmdSemitone <= instrument->normalRangeHi ? - &instrument->normalNotesSound : &instrument->highNotesSound; - - sameSound = (sound == (*layer).sound); - layer->sound = sound; - layer->freqScale = gNoteFrequencies[cmdSemitone] * (*sound).tuning; - } else { - layer->sound = NULL; - layer->freqScale = gNoteFrequencies[cmdSemitone]; - } - } - } - layer->delayUnused = layer->delay; - } - } - - if (layer->stopSomething == TRUE) { - if (layer->note != NULL || layer->continuousNotes) { - seq_channel_layer_note_decay(layer); - } - return; - } - - cmdSemitone = FALSE; - if (!layer->continuousNotes) { - cmdSemitone = TRUE; - } else if (layer->note == NULL || layer->status == SOUND_LOAD_STATUS_NOT_LOADED) { - cmdSemitone = TRUE; - } else if (sameSound == FALSE) { - seq_channel_layer_note_decay(layer); - cmdSemitone = TRUE; - } else if (layer->sound == NULL) { - init_synthetic_wave(layer->note, layer); - } - - if (cmdSemitone != FALSE) { - (*layer).note = alloc_note(layer); - } - - if (layer->note != NULL && layer->note->parentLayer == layer) { - note_vibrato_init(layer->note); - } -} diff --git a/src/audio/eu/data.c b/src/audio/eu/data.c new file mode 100644 index 00000000..ee7e587d --- /dev/null +++ b/src/audio/eu/data.c @@ -0,0 +1,390 @@ +#include + +#include "data.h" +#include "port.h" +#include "effects.h" + +struct ReverbSettingsEU sReverbSettings[] = { + { 0x04, 0x0c, 0x2fff }, + { 0x04, 0x0a, 0x47ff }, + { 0x04, 0x10, 0x2fff }, + { 0x04, 0x0e, 0x3fff }, + { 0x04, 0x0c, 0x4fff }, + { 0x04, 0x0a, 0x37ff } +}; +struct AudioSessionSettingsEU gAudioSessionPresets[] = { + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[2], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[3], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[4], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00004000, 0x00006e00, + 0x00003f00, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00004100, 0x00006e00, + 0x00004400, 0x00002a80 }, + { 0x00007d00, 0x01, 0x14, 0x01, 0x00, &sReverbSettings[5], 0x7fff, 0x0000, 0x00003500, 0x00006280, + 0x00004000, 0x00001b00 } +}; + +// Format: +// - frequency +// - max number of simultaneous notes +// - reverb downsample rate (makes the ring buffer be downsampled to save memory) +// - reverb window size (ring buffer size, length affects reverb delay) +// - reverb gain (0 = min reverb, 32767 = max reverb, 32769 to 65535 = louder and louder...) +// - volume +// - memory used for persistent sequences +// - memory used for persistent banks +// - memory used for temporary sequences +// - memory used for temporary banks +// gAudioCosineTable[k] = round((2**15 - 1) * cos(pi/2 * k / 127)). Unused. + +// Transforms a pitch scale factor in -127..127 into a frequency scale factor +// between -1 and +1 octave. +// gPitchBendFrequencyScale[k] = 0.5 * 2^(k/127) +f32 gPitchBendFrequencyScale[256] = { + 0.5f, + 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f, + 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, + 0.551614f, 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, + 0.579387f, 0.582558f, 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.601950f, 0.605245f, + 0.608557f, 0.611888f, 0.615236f, 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f, + 0.639196f, 0.642694f, 0.646212f, 0.649748f, 0.653304f, 0.656880f, 0.660475f, 0.664089f, 0.667724f, + 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, 0.689952f, 0.693727f, 0.697524f, 0.701341f, + 0.705180f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, 0.728655f, 0.732642f, 0.736652f, + 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.765340f, 0.769529f, 0.773740f, + 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f, 0.812696f, + 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.839750f, 0.844346f, 0.848966f, 0.853613f, + 0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.896590f, + 0.901496f, 0.906430f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.941730f, + 0.946884f, 0.952066f, 0.957277f, 0.962516f, 0.967783f, 0.973080f, 0.978405f, 0.983760f, 0.989144f, + 0.994557f, 1.0f, 1.005473f, 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f, + 1.044630f, 1.050347f, 1.056095f, 1.061875f, 1.067687f, 1.073530f, 1.079405f, 1.085312f, 1.091252f, + 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, 1.127579f, 1.133750f, 1.139955f, 1.146193f, + 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, 1.190831f, 1.197348f, 1.203901f, + 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, 1.257631f, 1.264514f, + 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f, 1.328178f, + 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f, + 1.402683f, 1.410360f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f, + 1.473304f, 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f, + 1.547481f, 1.555950f, 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f, + 1.625392f, 1.634287f, 1.643231f, 1.652224f, 1.661266f, 1.670358f, 1.679500f, 1.688691f, 1.697933f, + 1.707225f, 1.716569f, 1.725963f, 1.735409f, 1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f, + 1.793179f, 1.802993f, 1.812860f, 1.822782f, 1.832757f, 1.842788f, 1.852873f, 1.863013f, 1.873209f, + 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, 1.946159f, 1.956810f, 1.967520f, + 1.978287f, 1.989114f, 2.0f +}; + +// Frequencies for notes using the standard twelve-tone equal temperament scale. +// For indices 0..116, gNoteFrequencies[k] = 2^((k-39)/12). +// For indices 117..128, gNoteFrequencies[k] = 0.5 * 2^((k-39)/12). +// The 39 in the formula refers to piano key 40 (middle C, at 256 Hz) being +// the reference frequency, which is assigned value 1. +// clang-format off +f32 gNoteFrequencies[128] = { + 0.105112f, 0.111362f, 0.117984f, 0.125f, 0.132433f, 0.140308f, 0.148651f, 0.15749f, 0.166855f, 0.176777f, 0.187288f, 0.198425f, + 0.210224f, 0.222725f, 0.235969f, 0.25f, 0.264866f, 0.280616f, 0.297302f, 0.31498f, 0.33371f, 0.353553f, 0.374577f, 0.39685f, + 0.420448f, 0.445449f, 0.471937f, 0.5f, 0.529732f, 0.561231f, 0.594604f, 0.629961f, 0.66742f, 0.707107f, 0.749154f, 0.793701f, + 0.840897f, 0.890899f, 0.943875f, 1.0f, 1.059463f, 1.122462f, 1.189207f, 1.259921f, 1.33484f, 1.414214f, 1.498307f, 1.587401f, + 1.681793f, 1.781798f, 1.887749f, 2.0f, 2.118926f, 2.244924f, 2.378414f, 2.519842f, 2.66968f, 2.828428f, 2.996615f, 3.174803f, + 3.363586f, 3.563596f, 3.775498f, 4.0f, 4.237853f, 4.489849f, 4.756829f, 5.039685f, 5.33936f, 5.656855f, 5.993229f, 6.349606f, + 6.727173f, 7.127192f, 7.550996f, 8.0f, 8.475705f, 8.979697f, 9.513658f, 10.07937f, 10.67872f, 11.31371f, 11.986459f, 12.699211f, + 13.454346f, 14.254383f, 15.101993f, 16.0f, 16.95141f, 17.959394f, 19.027315f, 20.15874f, 21.35744f, 22.62742f, 23.972918f, 25.398422f, + 26.908691f, 28.508766f, 30.203985f, 32.0f, 33.90282f, 35.91879f, 38.05463f, 40.31748f, 42.71488f, 45.25484f, 47.945835f, 50.796844f, + 53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f, 85.42976f, 45.25484f, 47.945835f, 50.796844f, + 53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f +}; +// clang-format on + +// goes up by ~12 at each step for the first 4 values (starting from 0), then by ~6 +u8 gDefaultShortNoteVelocityTable[16] = { + 12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127, +}; + +// goes down by 26 at each step for the first 4 values (starting from 255), then by ~12 +u8 gDefaultShortNoteDurationTable[16] = { + 229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0, +}; + +struct AdsrEnvelope gDefaultEnvelope[] = { + { BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms + { BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds + { BSWAP16(ADSR_HANG), 0 } // then continue staying there +}; + +struct NoteSubEu gZeroNoteSub = { 0 }; +struct NoteSubEu gDefaultNoteSub = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL } }; + +s16 sSawtoothWaves[256] = { + 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, + 11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503, + 22527, 23551, 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, -0x7FFF, + -31743, -30719, -29695, -28671, -27647, -26623, -25599, -24575, -23551, -22527, -21503, + -0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239, + -9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, + 0, 0x7FF, 0xFFF, 0x17FF, 0x1FFF, 0x27FF, 0x2FFF, 0x37FF, 0x3FFF, 0x47FF, 0x4FFF, + 0x57FF, 0x5FFF, 0x67FF, 0x6FFF, 0x77FF, 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, + 0xb001, 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, 0xe001, 0xe801, 0xf001, 0xf801, 0x0000, + 0x07ff, 0x0fff, 0x17ff, 0x1fff, 0x27ff, 0x2fff, 0x37ff, 0x3fff, 0x47ff, 0x4fff, 0x57ff, + 0x5fff, 0x67ff, 0x6fff, 0x77ff, 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, 0xb001, + 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, 0xe001, 0xe801, 0xf001, 0xf801, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001 +}; +s16 sTriangleWaves[256] = { + 0x0000, 0x07ff, 0x0fff, 0x17ff, 0x1fff, 0x27ff, 0x2fff, 0x37ff, 0x3fff, 0x47ff, 0x4fff, 0x57ff, + 0x5fff, 0x67ff, 0x6fff, 0x77ff, 0x7fff, 0x77ff, 0x6fff, 0x67ff, 0x5fff, 0x57ff, 0x4fff, 0x47ff, + 0x3fff, 0x37ff, 0x2fff, 0x27ff, 0x1fff, 0x17ff, 0x0fff, 0x07ff, 0x0000, 0xf801, 0xf001, 0xe801, + 0xe001, 0xd801, 0xd001, 0xc801, 0xc001, 0xb801, 0xb001, 0xa801, 0xa001, 0x9801, 0x9001, 0x8801, + 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, 0xb001, 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, + 0xe001, 0xe801, 0xf001, 0xf801, 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x7fff, 0x6fff, 0x5fff, 0x4fff, 0x3fff, 0x2fff, 0x1fff, 0x0fff, 0x0000, 0xf001, 0xe001, 0xd001, + 0xc001, 0xb001, 0xa001, 0x9001, 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, 0x7fff, 0x6fff, 0x5fff, 0x4fff, + 0x3fff, 0x2fff, 0x1fff, 0x0fff, 0x0000, 0xf001, 0xe001, 0xd001, 0xc001, 0xb001, 0xa001, 0x9001, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, 0x0000, 0x1fff, 0x3fff, 0x5fff, + 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, + 0x8001, 0xa001, 0xc001, 0xe001, 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x7fff, 0x5fff, 0x3fff, 0x1fff, + 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, 0x0000, 0x1fff, 0x3fff, 0x5fff, + 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, + 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, + 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, + 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, + 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, + 0x0000, 0xc001, 0x8001, 0xc001, +}; +s16 sSineWaves[256] = { + 0x0000, 0x0c8b, 0x18f8, 0x2527, 0x30fb, 0x3c56, 0x471c, 0x5133, 0x5a81, 0x62f1, 0x6a6c, 0x70e1, + 0x7640, 0x7a7c, 0x7d89, 0x7f61, 0x7fff, 0x7f61, 0x7d89, 0x7a7c, 0x7640, 0x70e1, 0x6a6c, 0x62f1, + 0x5a81, 0x5133, 0x471c, 0x3c56, 0x30fb, 0x2527, 0x18f8, 0x0c8b, 0x0000, 0xf375, 0xe708, 0xdad9, + 0xcf05, 0xc3aa, 0xb8e4, 0xaecd, 0xa57f, 0x9d0f, 0x9594, 0x8f1f, 0x89c0, 0x8584, 0x8277, 0x809f, + 0x8001, 0x809f, 0x8277, 0x8584, 0x89c0, 0x8f1f, 0x9594, 0x9d0f, 0xa57f, 0xaecd, 0xb8e4, 0xc3aa, + 0xcf05, 0xdad9, 0xe708, 0xf375, 0x0000, 0x18f8, 0x30fb, 0x471c, 0x5a81, 0x6a6c, 0x7640, 0x7d89, + 0x7fff, 0x7d89, 0x7640, 0x6a6c, 0x5a81, 0x471c, 0x30fb, 0x18f8, 0x0000, 0xe708, 0xcf05, 0xb8e4, + 0xa57f, 0x9594, 0x89c0, 0x8277, 0x8001, 0x8277, 0x89c0, 0x9594, 0xa57f, 0xb8e4, 0xcf05, 0xe708, + 0x0000, 0x18f8, 0x30fb, 0x471c, 0x5a81, 0x6a6c, 0x7640, 0x7d89, 0x7fff, 0x7d89, 0x7640, 0x6a6c, + 0x5a81, 0x471c, 0x30fb, 0x18f8, 0x0000, 0xe708, 0xcf05, 0xb8e4, 0xa57f, 0x9594, 0x89c0, 0x8277, + 0x8001, 0x8277, 0x89c0, 0x9594, 0xa57f, 0xb8e4, 0xcf05, 0xe708, 0x0000, 0x30fb, 0x5a81, 0x7640, + 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, + 0x0000, 0x30fb, 0x5a81, 0x7640, 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, + 0x8001, 0x89c0, 0xa57f, 0xcf05, 0x0000, 0x30fb, 0x5a81, 0x7640, 0x7fff, 0x7640, 0x5a81, 0x30fb, + 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, 0x0000, 0x30fb, 0x5a81, 0x7640, + 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, + 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, + 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, + 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, + 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, + 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, + 0x0000, 0xa57f, 0x8001, 0xa57f, +}; +s16 sSquareWaves[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, + 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, + 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, + 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x8001, 0x8001, +}; +s16 sEuUnknownWave6[256] = { + 0x0000, 0x9ba7, 0x9b41, 0x6c9b, 0x9450, 0xadda, 0x569e, 0x189a, 0x69bf, 0xb79d, 0x6fe9, 0x08ec, + 0x0d34, 0x1aea, 0xce76, 0xad86, 0x2710, 0xa038, 0x7e28, 0x2fd8, 0x3af8, 0x3bfa, 0xd10b, 0x84c7, + 0xcd7f, 0x18f4, 0xd4c8, 0x76f8, 0x8994, 0xaa11, 0x73fb, 0x6c01, 0x0000, 0x93ff, 0x8c05, 0x55ef, + 0x766c, 0x8907, 0x2b38, 0xe70d, 0x3281, 0x7b38, 0x2ef5, 0xc407, 0xc508, 0xd027, 0x81d8, 0x5fc9, + 0xd8f0, 0x5279, 0x318a, 0xe517, 0xf2cc, 0xf713, 0x9017, 0x4864, 0x9641, 0xe765, 0xa962, 0x5227, + 0x6bb0, 0x9364, 0x64bf, 0x645a, 0x0000, 0x9b41, 0x9450, 0x569e, 0x69bf, 0x6fe9, 0x0d34, 0xce76, + 0x2710, 0x7e28, 0x3af8, 0xd10b, 0xcd7f, 0xd4c8, 0x8994, 0x73fb, 0x0000, 0x8c05, 0x766c, 0x2b38, + 0x3281, 0x2ef5, 0xc508, 0x81d8, 0xd8f0, 0x318a, 0xf2cc, 0x9017, 0x9641, 0xa962, 0x6bb0, 0x64bf, + 0x0000, 0x9b41, 0x9450, 0x569e, 0x69bf, 0x6fe9, 0x0d34, 0xce76, 0x2710, 0x7e28, 0x3af8, 0xd10b, + 0xcd7f, 0xd4c8, 0x8994, 0x73fb, 0x0000, 0x8c05, 0x766c, 0x2b38, 0x3281, 0x2ef5, 0xc508, 0x81d8, + 0xd8f0, 0x318a, 0xf2cc, 0x9017, 0x9641, 0xa962, 0x6bb0, 0x64bf, 0x0000, 0x9450, 0x69bf, 0x0d34, + 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, + 0x0000, 0x9450, 0x69bf, 0x0d34, 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, + 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, 0x0000, 0x9450, 0x69bf, 0x0d34, 0x2710, 0x3af8, 0xcd7f, 0x8994, + 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, 0x0000, 0x9450, 0x69bf, 0x0d34, + 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, + 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, + 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, + 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, + 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, + 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, + 0x0000, 0x3281, 0xd8f0, 0x9641, +}; +s16 gEuUnknownWave7[256] = { + 0x0000, 0x3fbc, 0x4eb4, 0x4f21, 0x6a49, 0x806f, 0x7250, 0x6a7b, 0x8d2e, 0xac0a, 0x98d6, 0x7832, + 0x7551, 0x71ca, 0x4eee, 0x3731, 0x4e20, 0x644d, 0x4a50, 0x23ba, 0x1b09, 0x119a, 0xe914, 0xccbe, + 0xe14e, 0xf8a3, 0xe47e, 0xc937, 0xd181, 0xde39, 0xcfc6, 0xcf94, 0x0000, 0x306c, 0x303a, 0x21c7, + 0x2e7f, 0x36c8, 0x1b82, 0x075e, 0x1eb2, 0x3341, 0x16ec, 0xee67, 0xe4f7, 0xdc45, 0xb5b0, 0x9bb4, + 0xb1e0, 0xc8ce, 0xb112, 0x8e37, 0x8aaf, 0x87cd, 0x672a, 0x53f7, 0x72d2, 0x9584, 0x8db0, 0x7f92, + 0x95b7, 0xb0de, 0xb14c, 0xc045, 0x0000, 0x4eb4, 0x6a49, 0x7250, 0x8d2e, 0x98d6, 0x7551, 0x4eee, + 0x4e20, 0x4a50, 0x1b09, 0xe914, 0xe14e, 0xe47e, 0xd181, 0xcfc6, 0x0000, 0x303a, 0x2e7f, 0x1b82, + 0x1eb2, 0x16ec, 0xe4f7, 0xb5b0, 0xb1e0, 0xb112, 0x8aaf, 0x672a, 0x72d2, 0x8db0, 0x95b7, 0xb14c, + 0x0000, 0x4eb4, 0x6a49, 0x7250, 0x8d2e, 0x98d6, 0x7551, 0x4eee, 0x4e20, 0x4a50, 0x1b09, 0xe914, + 0xe14e, 0xe47e, 0xd181, 0xcfc6, 0x0000, 0x303a, 0x2e7f, 0x1b82, 0x1eb2, 0x16ec, 0xe4f7, 0xb5b0, + 0xb1e0, 0xb112, 0x8aaf, 0x672a, 0x72d2, 0x8db0, 0x95b7, 0xb14c, 0x0000, 0x6a49, 0x8d2e, 0x7551, + 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, + 0x0000, 0x6a49, 0x8d2e, 0x7551, 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, + 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, 0x0000, 0x6a49, 0x8d2e, 0x7551, 0x4e20, 0x1b09, 0xe14e, 0xd181, + 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, 0x0000, 0x6a49, 0x8d2e, 0x7551, + 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, + 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, + 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, + 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, + 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, + 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, + 0x0000, 0x1eb2, 0xb1e0, 0x72d2, +}; +s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 }; + +u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 }; +u16 gHeadsetPanQuantization[0x10] = { + 0x40, 0x40, 0x30, 0x30, 0x20, 0x20, 0x10, 0, 0, 0, +}; + +s16 euUnknownData_80301950[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, +}; + +// Linearly interpolated between +// f(0/2 * 127) = 1 +// f(1/2 * 127) = 1/sqrt(2) +// f(2/2 * 127) = 0 +f32 gHeadsetPanVolume[128] = { + 1.0f, 0.995386f, 0.990772f, 0.986157f, 0.981543f, 0.976929f, 0.972315f, 0.967701f, 0.963087f, + 0.958472f, 0.953858f, 0.949244f, 0.94463f, 0.940016f, 0.935402f, 0.930787f, 0.926173f, 0.921559f, + 0.916945f, 0.912331f, 0.907717f, 0.903102f, 0.898488f, 0.893874f, 0.88926f, 0.884646f, 0.880031f, + 0.875417f, 0.870803f, 0.866189f, 0.861575f, 0.856961f, 0.852346f, 0.847732f, 0.843118f, 0.838504f, + 0.83389f, 0.829276f, 0.824661f, 0.820047f, 0.815433f, 0.810819f, 0.806205f, 0.801591f, 0.796976f, + 0.792362f, 0.787748f, 0.783134f, 0.77852f, 0.773906f, 0.769291f, 0.764677f, 0.760063f, 0.755449f, + 0.750835f, 0.74622f, 0.741606f, 0.736992f, 0.732378f, 0.727764f, 0.72315f, 0.718535f, 0.713921f, + 0.709307f, 0.70537f, 0.70211f, 0.69885f, 0.695591f, 0.692331f, 0.689071f, 0.685811f, 0.682551f, + 0.679291f, 0.676031f, 0.672772f, 0.669512f, 0.666252f, 0.662992f, 0.659732f, 0.656472f, 0.653213f, + 0.649953f, 0.646693f, 0.643433f, 0.640173f, 0.636913f, 0.633654f, 0.630394f, 0.627134f, 0.623874f, + 0.620614f, 0.617354f, 0.614094f, 0.610835f, 0.607575f, 0.604315f, 0.601055f, 0.597795f, 0.594535f, + 0.591276f, 0.588016f, 0.584756f, 0.581496f, 0.578236f, 0.574976f, 0.571717f, 0.568457f, 0.565197f, + 0.561937f, 0.558677f, 0.555417f, 0.552157f, 0.548898f, 0.545638f, 0.542378f, 0.539118f, 0.535858f, + 0.532598f, 0.529339f, 0.526079f, 0.522819f, 0.519559f, 0.516299f, 0.513039f, 0.50978f, 0.50652f, + 0.50326f, 0.5f +}; + +// Linearly interpolated between +// f(0/4 * 127) = 1/sqrt(2) +// f(1/4 * 127) = 1 +// f(2/4 * 127) = 1/sqrt(2) +// f(3/4 * 127) = 0 +// f(4/4 * 127) = 1/sqrt(8) +f32 gStereoPanVolume[128] = { + 0.707f, 0.716228f, 0.725457f, 0.734685f, 0.743913f, 0.753142f, 0.76237f, 0.771598f, 0.780827f, + 0.790055f, 0.799283f, 0.808512f, 0.81774f, 0.826968f, 0.836197f, 0.845425f, 0.854654f, 0.863882f, + 0.87311f, 0.882339f, 0.891567f, 0.900795f, 0.910024f, 0.919252f, 0.92848f, 0.937709f, 0.946937f, + 0.956165f, 0.965394f, 0.974622f, 0.98385f, 0.993079f, 0.997693f, 0.988465f, 0.979236f, 0.970008f, + 0.960779f, 0.951551f, 0.942323f, 0.933095f, 0.923866f, 0.914638f, 0.905409f, 0.896181f, 0.886953f, + 0.877724f, 0.868496f, 0.859268f, 0.850039f, 0.840811f, 0.831583f, 0.822354f, 0.813126f, 0.803898f, + 0.794669f, 0.785441f, 0.776213f, 0.766984f, 0.757756f, 0.748528f, 0.739299f, 0.730071f, 0.720843f, + 0.711614f, 0.695866f, 0.673598f, 0.651331f, 0.629063f, 0.606795f, 0.584528f, 0.56226f, 0.539992f, + 0.517724f, 0.495457f, 0.473189f, 0.450921f, 0.428654f, 0.406386f, 0.384118f, 0.36185f, 0.339583f, + 0.317315f, 0.295047f, 0.27278f, 0.250512f, 0.228244f, 0.205976f, 0.183709f, 0.161441f, 0.139173f, + 0.116905f, 0.094638f, 0.07237f, 0.050102f, 0.027835f, 0.005567f, 0.00835f, 0.019484f, 0.030618f, + 0.041752f, 0.052886f, 0.06402f, 0.075154f, 0.086287f, 0.097421f, 0.108555f, 0.119689f, 0.130823f, + 0.141957f, 0.153091f, 0.164224f, 0.175358f, 0.186492f, 0.197626f, 0.20876f, 0.219894f, 0.231028f, + 0.242161f, 0.253295f, 0.264429f, 0.275563f, 0.286697f, 0.297831f, 0.308965f, 0.320098f, 0.331232f, + 0.342366f, 0.3535f +}; + +// gDefaultVolume[k] = cos(pi/2 * k / 127) +f32 gDefaultPanVolume[128] = { + 1.0f, 0.999924f, 0.999694f, 0.999312f, 0.998776f, 0.998088f, 0.997248f, 0.996254f, 0.995109f, + 0.993811f, 0.992361f, 0.990759f, 0.989006f, 0.987101f, 0.985045f, 0.982839f, 0.980482f, 0.977976f, + 0.97532f, 0.972514f, 0.96956f, 0.966457f, 0.963207f, 0.959809f, 0.956265f, 0.952574f, 0.948737f, + 0.944755f, 0.940629f, 0.936359f, 0.931946f, 0.92739f, 0.922692f, 0.917853f, 0.912873f, 0.907754f, + 0.902497f, 0.897101f, 0.891567f, 0.885898f, 0.880093f, 0.874153f, 0.868079f, 0.861873f, 0.855535f, + 0.849066f, 0.842467f, 0.835739f, 0.828884f, 0.821901f, 0.814793f, 0.807561f, 0.800204f, 0.792725f, + 0.785125f, 0.777405f, 0.769566f, 0.76161f, 0.753536f, 0.745348f, 0.737045f, 0.72863f, 0.720103f, + 0.711466f, 0.70272f, 0.693867f, 0.684908f, 0.675843f, 0.666676f, 0.657406f, 0.648036f, 0.638567f, + 0.629f, 0.619337f, 0.609579f, 0.599728f, 0.589785f, 0.579752f, 0.56963f, 0.559421f, 0.549126f, + 0.538748f, 0.528287f, 0.517745f, 0.507124f, 0.496425f, 0.485651f, 0.474802f, 0.46388f, 0.452888f, + 0.441826f, 0.430697f, 0.419502f, 0.408243f, 0.396921f, 0.385538f, 0.374097f, 0.362598f, 0.351044f, + 0.339436f, 0.327776f, 0.316066f, 0.304308f, 0.292503f, 0.280653f, 0.268761f, 0.256827f, 0.244854f, + 0.232844f, 0.220798f, 0.208718f, 0.196606f, 0.184465f, 0.172295f, 0.160098f, 0.147877f, 0.135634f, + 0.12337f, 0.111087f, 0.098786f, 0.086471f, 0.074143f, 0.061803f, 0.049454f, 0.037097f, 0.024734f, + 0.012368f, 0.0f +}; + +s16 gTatumsPerBeat = TATUMS_PER_BEAT; +s8 gUnusedCount80333EE8 = UNUSED_COUNT_80333EE8; +s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_HEAP_SIZE); +s32 gAudioInitPoolSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_INIT_POOL_SIZE); +volatile s32 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; + +u8 bufferDelete2[12] = { 0 }; +u8 D_EU_80302010 = 0; +u8 D_EU_80302014 = 0; + +OSMesgQueue *OSMesgQueue0 = &OSMesgQueue0Data; +OSMesgQueue *OSMesgQueue1 = &OSMesgQueue1Data; +OSMesgQueue *OSMesgQueue2 = &OSMesgQueue2Data; +OSMesgQueue *OSMesgQueue3 = &OSMesgQueue3Data; + +// .bss + +volatile s32 gAudioFrameCount; + +s32 gCurrAudioFrameDmaCount; + +s32 gAudioTaskIndex; +s32 gCurrAiBufferIndex; + +u64 *gAudioCmdBuffers[2]; +u64 *gAudioCmd; + +struct SPTask *gAudioTask; +struct SPTask gAudioTasks[2]; + +f32 D_EU_802298D0; +s32 gRefreshRate; + +s16 *gAiBuffers[NUMAIBUFFERS]; +s16 gAiBufferLengths[NUMAIBUFFERS]; + +u32 gAudioRandom; + +s32 gAudioErrorFlags; + +u64 gAudioGlobalsEndMarker; diff --git a/src/audio/eu/data.h b/src/audio/eu/data.h new file mode 100644 index 00000000..30b4b2c7 --- /dev/null +++ b/src/audio/eu/data.h @@ -0,0 +1,85 @@ +#ifndef AUDIO_DATA_H +#define AUDIO_DATA_H + +#include + +#include "internal.h" +#include "types.h" + +#define AUDIO_LOCK_UNINITIALIZED 0 +#define AUDIO_LOCK_NOT_LOADING 0x76557364 +#define AUDIO_LOCK_LOADING 0x19710515 + +#define NUMAIBUFFERS 3 + +// constant .data +extern struct AudioSessionSettingsEU gAudioSessionPresets[]; +extern u16 D_80332388[128]; // unused + +extern f32 gPitchBendFrequencyScale[256]; +extern f32 gNoteFrequencies[128]; + +extern u8 gDefaultShortNoteVelocityTable[16]; +extern u8 gDefaultShortNoteDurationTable[16]; +extern s8 gVibratoCurve[16]; +extern struct AdsrEnvelope gDefaultEnvelope[3]; + +extern s16 gEuUnknownWave7[256]; +extern s16 *gWaveSamples[6]; + +extern u8 euUnknownData_8030194c[4]; +extern u16 gHeadsetPanQuantization[0x10]; +extern s16 euUnknownData_80301950[64]; +extern struct NoteSubEu gZeroNoteSub; +extern struct NoteSubEu gDefaultNoteSub; +extern f32 gHeadsetPanVolume[128]; +extern f32 gStereoPanVolume[128]; +extern f32 gDefaultPanVolume[128]; + +extern f32 gVolRampingLhs136[128]; +extern f32 gVolRampingRhs136[128]; +extern f32 gVolRampingLhs144[128]; +extern f32 gVolRampingRhs144[128]; +extern f32 gVolRampingLhs128[128]; +extern f32 gVolRampingRhs128[128]; + +// non-constant .data +extern s16 gTatumsPerBeat; +extern s8 gUnusedCount80333EE8; +extern s32 gAudioHeapSize; // AUDIO_HEAP_SIZE +extern s32 gAudioInitPoolSize; // AUDIO_INIT_POOL_SIZE +extern volatile s32 gAudioLoadLock; + +// .bss +extern volatile s32 gAudioFrameCount; + +// number of DMAs performed during this frame +extern s32 gCurrAudioFrameDmaCount; + +extern s32 gAudioTaskIndex; +extern s32 gCurrAiBufferIndex; + +extern u64 *gAudioCmdBuffers[2]; +extern u64 *gAudioCmd; + +extern struct SPTask *gAudioTask; +extern struct SPTask gAudioTasks[2]; + +extern f32 D_EU_802298D0; +extern s32 gRefreshRate; + +extern s16 *gAiBuffers[NUMAIBUFFERS]; +extern s16 gAiBufferLengths[NUMAIBUFFERS]; +#define AIBUFFER_LEN (0xa0 * 17) + +extern u32 gUnused80226E58[0x10]; +extern u16 gUnused80226E98[0x10]; + +extern u32 gAudioRandom; +extern s32 gAudioErrorFlags; + +#define UNUSED_COUNT_80333EE8 24 +#define AUDIO_HEAP_SIZE 0x2c500 +#define AUDIO_INIT_POOL_SIZE 0x2c00 + +#endif // AUDIO_DATA_H diff --git a/src/audio/eu/effects.c b/src/audio/eu/effects.c new file mode 100644 index 00000000..8ad2a1c4 --- /dev/null +++ b/src/audio/eu/effects.c @@ -0,0 +1,314 @@ +#include + +#include "effects.h" +#include "load.h" +#include "data.h" +#include "seqplayer.h" + +void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 recalculateVolume) { + f32 channelVolume; + s32 i; + + if (seqChannel->changes.as_bitfields.volume || recalculateVolume) { + channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->appliedFadeVolume; + if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) { + channelVolume = seqChannel->seqPlayer->muteVolumeScale * channelVolume; + } + seqChannel->appliedVolume = channelVolume; + } + + if (seqChannel->changes.as_bitfields.pan) { + seqChannel->pan = seqChannel->newPan * seqChannel->panChannelWeight; + } + + for (i = 0; i < 4; i++) { + struct SequenceChannelLayer *layer = seqChannel->layers[i]; + if (layer != NULL && layer->enabled && layer->note != NULL) { + if (layer->notePropertiesNeedInit) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + layer->noteVelocity = layer->velocitySquare * seqChannel->appliedVolume; + layer->notePan = (seqChannel->pan + layer->pan * (0x80 - seqChannel->panChannelWeight)) >> 7; + layer->notePropertiesNeedInit = FALSE; + } else { + if (seqChannel->changes.as_bitfields.freqScale) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + } + if (seqChannel->changes.as_bitfields.volume || recalculateVolume) { + layer->noteVelocity = layer->velocitySquare * seqChannel->appliedVolume; + } + if (seqChannel->changes.as_bitfields.pan) { + layer->notePan = (seqChannel->pan + layer->pan * (0x80 - seqChannel->panChannelWeight)) >> 7; + } + } + } + } + seqChannel->changes.as_u8 = 0; +} + +void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { + s32 i; + + if (seqPlayer->fadeRemainingFrames != 0) { + seqPlayer->fadeVolume += seqPlayer->fadeVelocity; + seqPlayer->recalculateVolume = TRUE; + + if (seqPlayer->fadeVolume > 1) { + seqPlayer->fadeVolume = 1; + } + if (seqPlayer->fadeVolume < 0) { + seqPlayer->fadeVolume = 0; + } + + if (--seqPlayer->fadeRemainingFrames == 0) { + if (seqPlayer->state == 2) { + sequence_player_disable(seqPlayer); + return; + } + } + } + + if (seqPlayer->recalculateVolume) { + seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; + } + + // Process channels + for (i = 0; i < CHANNELS_MAX; i++) { + if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE + && seqPlayer->channels[i]->enabled == TRUE) { + sequence_channel_process_sound(seqPlayer->channels[i], seqPlayer->recalculateVolume); + } + } + + seqPlayer->recalculateVolume = FALSE; +} + +f32 get_portamento_freq_scale(struct Portamento *p) { + u32 v0; + f32 result; + + p->cur += p->speed; + v0 = (u32) p->cur; + + if (v0 > 127) + { + v0 = 127; + } + + result = 1.0f + p->extent * (gPitchBendFrequencyScale[v0 + 128] - 1.0f); + return result; +} + +s16 get_vibrato_pitch_change(struct VibratoState *vib) { + s32 index; + vib->time += (s32) vib->rate; + index = (vib->time >> 10) & 0x3F; + return vib->curve[index] >> 8; +} + +f32 get_vibrato_freq_scale(struct VibratoState *vib) { + s32 pitchChange; + f32 extent; + f32 result; + + if (vib->delay != 0) { + vib->delay--; + return 1; + } + + if (vib->extentChangeTimer) { + if (vib->extentChangeTimer == 1) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; + } else { + vib->extent += + ((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer; + } + + vib->extentChangeTimer--; + } else if (vib->seqChannel->vibratoExtentTarget != (s32) vib->extent) { + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; + } + } + + if (vib->rateChangeTimer) { + if (vib->rateChangeTimer == 1) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; + } else { + vib->rate += ((s32) vib->seqChannel->vibratoRateTarget - vib->rate) / (s32) vib->rateChangeTimer; + } + + vib->rateChangeTimer--; + } else if (vib->seqChannel->vibratoRateTarget != (s32) vib->rate) { + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; + } + } + + if (vib->extent == 0) { + return 1.0f; + } + + pitchChange = get_vibrato_pitch_change(vib); + extent = (f32) vib->extent / 4096.0f; + + result = 1.0f + extent * (gPitchBendFrequencyScale[pitchChange + 128] - 1.0f); + return result; +} + +void note_vibrato_update(struct Note *note) { + if (note->portamento.mode != 0) { + note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); + } + if (note->vibratoState.active && note->parentLayer != NO_LAYER) { + note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); + } +} + +void note_vibrato_init(struct Note *note) { + struct VibratoState *vib; + UNUSED struct SequenceChannel *seqChannel; + struct NotePlaybackState *seqPlayerState = (struct NotePlaybackState *) ¬e->priority; + + note->vibratoFreqScale = 1.0f; + note->portamentoFreqScale = 1.0f; + + vib = ¬e->vibratoState; + + vib->active = TRUE; + vib->time = 0; + + vib->curve = gWaveSamples[2]; + vib->seqChannel = note->parentLayer->seqChannel; + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentTarget); + } else { + vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentStart); + } + + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateTarget); + } else { + vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateStart); + } + vib->delay = vib->seqChannel->vibratoDelay; + + seqPlayerState->portamento = seqPlayerState->parentLayer->portamento; +} + +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, UNUSED s16 *volOut) { + adsr->action = 0; + adsr->state = ADSR_STATE_DISABLED; + adsr->delay = 0; + adsr->envelope = envelope; + adsr->current = 0.0f; +} + +f32 adsr_update(struct AdsrState *adsr) { + u8 action = adsr->action; + u8 state = adsr->state; + switch (state) { + case ADSR_STATE_DISABLED: + return 0; + + case ADSR_STATE_INITIAL: { + if (action & ADSR_ACTION_HANG) { + adsr->state = ADSR_STATE_HANG; + break; + } + // fallthrough + } + + case ADSR_STATE_START_LOOP: + adsr->envIndex = 0; + adsr->state = ADSR_STATE_LOOP; + // fallthrough + + case ADSR_STATE_LOOP: + adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay); + switch (adsr->delay) { + case ADSR_DISABLE: + adsr->state = ADSR_STATE_DISABLED; + break; + case ADSR_HANG: + adsr->state = ADSR_STATE_HANG; + break; + case ADSR_GOTO: + adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg); + break; + case ADSR_RESTART: + adsr->state = ADSR_STATE_INITIAL; + break; + + default: + if (adsr->delay >= 4) { + adsr->delay = adsr->delay * gAudioBufferParameters.updatesPerFrame + / 4; + } + adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0; + adsr->target = adsr->target * adsr->target; + adsr->velocity = (adsr->target - adsr->current) / adsr->delay; + adsr->state = ADSR_STATE_FADE; + adsr->envIndex++; + break; + } + if (adsr->state != ADSR_STATE_FADE) { + break; + } + // fallthrough + + case ADSR_STATE_FADE: + adsr->current += adsr->velocity; + if (--adsr->delay <= 0) { + adsr->state = ADSR_STATE_LOOP; + } + // fallthrough + + case ADSR_STATE_HANG: + break; + + case ADSR_STATE_DECAY: + case ADSR_STATE_RELEASE: { + adsr->current -= adsr->fadeOutVel; + if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { + if (adsr->current < adsr->sustain) { + adsr->current = adsr->sustain; + adsr->delay = 128; + adsr->state = ADSR_STATE_SUSTAIN; + } + break; + } + + if (adsr->current < 0) { + adsr->current = 0.0f; + adsr->state = ADSR_STATE_DISABLED; + } + break; + } + + case ADSR_STATE_SUSTAIN: + adsr->delay -= 1; + if (adsr->delay == 0) { + adsr->state = ADSR_STATE_RELEASE; + } + break; + } + + if ((action & ADSR_ACTION_DECAY)) { + adsr->state = ADSR_STATE_DECAY; + adsr->action = action & ~ADSR_ACTION_DECAY; + } + + if ((action & ADSR_ACTION_RELEASE)) { + adsr->state = ADSR_STATE_RELEASE; + adsr->action = action & ~ADSR_ACTION_RELEASE; + } + + if (adsr->current < 0.0f) { + return 0.0f; + } + if (adsr->current > 1.0f) { + eu_stubbed_printf_1("Audio:Envp: overflow %f\n", adsr->current); + return 1.0f; + } + return adsr->current; +} diff --git a/src/audio/effects.h b/src/audio/eu/effects.h similarity index 90% rename from src/audio/effects.h rename to src/audio/eu/effects.h index 05491e80..cdedf1e4 100644 --- a/src/audio/effects.h +++ b/src/audio/eu/effects.h @@ -37,10 +37,6 @@ void sequence_player_process_sound(struct SequencePlayer *seqPlayer); void note_vibrato_update(struct Note *note); void note_vibrato_init(struct Note *note); void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) f32 adsr_update(struct AdsrState *adsr); -#else -s32 adsr_update(struct AdsrState *adsr); -#endif #endif // AUDIO_EFFECTS_H diff --git a/src/audio/globals_start.c b/src/audio/eu/globals_start.c similarity index 100% rename from src/audio/globals_start.c rename to src/audio/eu/globals_start.c diff --git a/src/audio/eu/heap.c b/src/audio/eu/heap.c new file mode 100644 index 00000000..ed671271 --- /dev/null +++ b/src/audio/eu/heap.c @@ -0,0 +1,677 @@ +#include + +#include "heap.h" +#include "data.h" +#include "load.h" +#include "synthesis.h" +#include "seqplayer.h" +#include "effects.h" + +#define ALIGN16(val) (((val) + 0xF) & ~0xF) + +struct PoolSplit { + u32 wantSeq; + u32 wantBank; + u32 wantUnused; + u32 wantCustom; +}; // size = 0x10 + +struct PoolSplit2 { + u32 wantPersistent; + u32 wantTemporary; +}; // size = 0x8 + +struct SoundAllocPool gAudioSessionPool; +struct SoundAllocPool gAudioInitPool; +struct SoundAllocPool gNotesAndBuffersPool; +u8 sAudioHeapPad[0x20]; // probably two unused pools +struct SoundAllocPool gSeqAndBankPool; +struct SoundAllocPool gPersistentCommonPool; +struct SoundAllocPool gTemporaryCommonPool; + +struct SoundMultiPool gSeqLoadedPool; +struct SoundMultiPool gBankLoadedPool; +struct SoundMultiPool gUnusedLoadedPool; + +struct PoolSplit sSessionPoolSplit; +struct PoolSplit2 sSeqAndBankPoolSplit; +struct PoolSplit sPersistentCommonPoolSplit; +struct PoolSplit sTemporaryCommonPoolSplit; + +u8 gBankLoadStatus[0x40]; +u8 gSeqLoadStatus[0x100]; + +volatile u8 gAudioResetStatus; +u8 gAudioResetPresetIdToLoad; +s32 gAudioResetFadeOutFramesLeft; + +u8 gAudioUnusedBuffer[0x1000]; + +extern s32 gMaxAudioCmds; + +/** + * Assuming 'k' in [9, 24], + * Computes a newton's method step for f(x) = x^k - d + */ +f64 root_newton_step(f64 x, s32 k, f64 d) { + f64 deg2 = x * x; + f64 deg4 = deg2 * deg2; + f64 deg8 = deg4 * deg4; + s32 degree = k - 9; + f64 fx; + + f64 deriv = deg8; + if (degree & 1) { + deriv *= x; + } + if (degree & 2) { + deriv *= deg2; + } + if (degree & 4) { + deriv *= deg4; + } + if (degree & 8) { + deriv *= deg8; + } + fx = deriv * x - d; + deriv = k * deriv; + return x - fx / deriv; +} + +/** + * Assuming 'k' in [9, 24], + * Computes d ^ (1/k) + * + * @return the root, or 1.0 if d is 0 + */ +f64 kth_root(f64 d, s32 k) { + f64 root = 1.5; + f64 next; + f64 diff; + s32 i; + if (d == 0.0) { + root = 1.0; + } else { + for (i = 0; i < 64; i++) { + if (1) { + } + next = root_newton_step(root, k, d); + diff = next - root; + + if (diff < 0) { + diff = -diff; + } + + if (diff < 1e-07) { + root = next; + break; + } else { + root = next; + } + } + } + + return root; +} + +void build_vol_rampings_table(s32 UNUSED unused, s32 len) { + s32 i; + s32 step; + s32 d; + s32 k = len / 8; + + for (step = 0, i = 0; i < 0x400; step += 32, i++) { + d = step; + if (step == 0) { + d = 1; + } + + gLeftVolRampings[0][i] = kth_root( d, k - 1); + gRightVolRampings[0][i] = kth_root(1.0 / d, k - 1) * 65536.0; + gLeftVolRampings[1][i] = kth_root( d, k); + gRightVolRampings[1][i] = kth_root(1.0 / d, k) * 65536.0; + gLeftVolRampings[2][i] = kth_root( d, k + 1); + gRightVolRampings[2][i] = kth_root(1.0 / d, k + 1) * 65536.0; + } +} + +void reset_bank_and_seq_load_status(void) { + s32 i; + + for (i = 0; i < 64; i++) { + gBankLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; + } + + for (i = 0; i < 256; i++) { + gSeqLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; + } +} + +void discard_bank(s32 bankId) { + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + struct Note *note = &gNotes[i]; + + if (note->noteSubEu.bankId == bankId) + { + // (These prints are unclear. Arguments are picked semi-randomly.) + eu_stubbed_printf_1("Warning:Kill Note %x \n", i); + if (note->priority >= NOTE_PRIORITY_MIN) + { + eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId, + bankId, note->priority); + eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n"); + note->parentLayer->enabled = FALSE; + note->parentLayer->finished = TRUE; + } + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(&gNoteFreeLists.disabled, ¬e->listItem); + } + } +} + +void discard_sequence(s32 seqId) { + s32 i; + + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + if (gSequencePlayers[i].enabled && gSequencePlayers[i].seqId == seqId) { + sequence_player_disable(&gSequencePlayers[i]); + } + } +} + +void *soundAlloc(struct SoundAllocPool *pool, u32 size) { + u8 *start; + u8 *pos; + u32 alignedSize = ALIGN16(size); + + start = pool->cur; + if (start + alignedSize <= pool->start + pool->size) { + pool->cur += alignedSize; + for (pos = start; pos < pool->cur; pos++) { + *pos = 0; + } + } else { + eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size); + return NULL; + } + return start; +} + +void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size) { + pool->cur = pool->start = (u8 *) ALIGN16((uintptr_t) memAddr); + pool->size = size; + pool->numAllocatedEntries = 0; +} + +void persistent_pool_clear(struct PersistentPool *persistent) { + persistent->pool.numAllocatedEntries = 0; + persistent->pool.cur = persistent->pool.start; + persistent->numEntries = 0; +} + +void temporary_pool_clear(struct TemporaryPool *temporary) { + temporary->pool.numAllocatedEntries = 0; + temporary->pool.cur = temporary->pool.start; + temporary->nextSide = 0; + temporary->entries[0].ptr = temporary->pool.start; + temporary->entries[1].ptr = temporary->pool.start + temporary->pool.size; + temporary->entries[0].id = -1; + temporary->entries[1].id = -1; +} + +void unused_803160F8(struct SoundAllocPool *pool) { + pool->numAllocatedEntries = 0; + pool->cur = pool->start; +} + +void sound_init_main_pools(s32 sizeForAudioInitPool) { + sound_alloc_pool_init(&gAudioInitPool, gAudioHeap, sizeForAudioInitPool); + sound_alloc_pool_init(&gAudioSessionPool, gAudioHeap + sizeForAudioInitPool, gAudioHeapSize - sizeForAudioInitPool); +} + +void session_pools_init(struct PoolSplit *a) { + gAudioSessionPool.cur = gAudioSessionPool.start; + sound_alloc_pool_init(&gNotesAndBuffersPool, soundAlloc(&gAudioSessionPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gSeqAndBankPool, soundAlloc(&gAudioSessionPool, a->wantCustom), a->wantCustom); +} + +void seq_and_bank_pool_init(struct PoolSplit2 *a) { + gSeqAndBankPool.cur = gSeqAndBankPool.start; + sound_alloc_pool_init(&gPersistentCommonPool, soundAlloc(&gSeqAndBankPool, a->wantPersistent), a->wantPersistent); + sound_alloc_pool_init(&gTemporaryCommonPool, soundAlloc(&gSeqAndBankPool, a->wantTemporary), a->wantTemporary); +} + +void persistent_pools_init(struct PoolSplit *a) { + gPersistentCommonPool.cur = gPersistentCommonPool.start; + sound_alloc_pool_init(&gSeqLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantUnused), + a->wantUnused); + persistent_pool_clear(&gSeqLoadedPool.persistent); + persistent_pool_clear(&gBankLoadedPool.persistent); + persistent_pool_clear(&gUnusedLoadedPool.persistent); +} + +void temporary_pools_init(struct PoolSplit *a) { + gTemporaryCommonPool.cur = gTemporaryCommonPool.start; + sound_alloc_pool_init(&gSeqLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantUnused), + a->wantUnused); + temporary_pool_clear(&gSeqLoadedPool.temporary); + temporary_pool_clear(&gBankLoadedPool.temporary); + temporary_pool_clear(&gUnusedLoadedPool.temporary); +} + +void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) { + // arg3 = 0, 1 or 2? + + struct TemporaryPool *tp; + struct SoundAllocPool *pool; + void *ret; + u16 firstVal; + u16 secondVal; + u32 nullID = -1; + UNUSED s32 i; + u8 *table; + u8 isSound; + + if (arg3 == 0) { + tp = &arg0->temporary; + if (arg0 == &gSeqLoadedPool) { + table = gSeqLoadStatus; + isSound = FALSE; + } else if (arg0 == &gBankLoadedPool) { + table = gBankLoadStatus; + isSound = TRUE; + } + + firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]); + secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]); + + if (0) { + // It's unclear where these string literals go. + eu_stubbed_printf_0("DataHeap Not Allocate \n"); + eu_stubbed_printf_1("StayHeap Not Allocate %d\n", 0); + eu_stubbed_printf_1("AutoHeap Not Allocate %d\n", 0); + } + + if (firstVal == SOUND_LOAD_STATUS_NOT_LOADED) { + tp->nextSide = 0; + } else if (secondVal == SOUND_LOAD_STATUS_NOT_LOADED) { + tp->nextSide = 1; + } else { + eu_stubbed_printf_0("WARNING: NO FREE AUTOSEQ AREA.\n"); + if ((firstVal == SOUND_LOAD_STATUS_DISCARDABLE) && (secondVal == SOUND_LOAD_STATUS_DISCARDABLE)) { + // Use the opposite side from last time. + } else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { + tp->nextSide = 0; + } else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) { + tp->nextSide = 1; + } else { + eu_stubbed_printf_0("WARNING: NO STOP AUTO AREA.\n"); + eu_stubbed_printf_0(" AND TRY FORCE TO STOP SIDE \n"); + if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) { + tp->nextSide = 0; + } else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) { + tp->nextSide = 1; + } else { + // Both left and right sides are being loaded into. + eu_stubbed_printf_0("TWO SIDES ARE LOADING... ALLOC CANCELED.\n"); + return NULL; + } + } + } + + pool = &arg0->temporary.pool; + if (tp->entries[tp->nextSide].id != (s8)nullID) { + table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED; + if (isSound == TRUE) { + discard_bank(tp->entries[tp->nextSide].id); + } + } + + switch (tp->nextSide) { + case 0: + tp->entries[0].ptr = pool->start; + tp->entries[0].id = id; + tp->entries[0].size = size; + + pool->cur = pool->start + size; + + if (tp->entries[1].ptr < pool->cur) { + eu_stubbed_printf_0("WARNING: Before Area Overlaid After."); + + // Throw out the entry on the other side if it doesn't fit. + // (possible @bug: what if it's currently being loaded?) + table[tp->entries[1].id] = SOUND_LOAD_STATUS_NOT_LOADED; + + switch (isSound) { + case FALSE: + discard_sequence(tp->entries[1].id); + break; + case TRUE: + discard_bank(tp->entries[1].id); + break; + } + + tp->entries[1].id = (s32)nullID; + tp->entries[1].ptr = pool->start + pool->size; + } + + ret = tp->entries[0].ptr; + break; + + case 1: + tp->entries[1].ptr = pool->start + pool->size - size - 0x10; + tp->entries[1].id = id; + tp->entries[1].size = size; + + if (tp->entries[1].ptr < pool->cur) { + eu_stubbed_printf_0("WARNING: After Area Overlaid Before."); + + table[tp->entries[0].id] = SOUND_LOAD_STATUS_NOT_LOADED; + + switch (isSound) { + case FALSE: + discard_sequence(tp->entries[0].id); + break; + case TRUE: + discard_bank(tp->entries[0].id); + break; + } + + tp->entries[0].id = (s32)nullID; + pool->cur = pool->start; + } + + ret = tp->entries[1].ptr; + break; + + default: + eu_stubbed_printf_1("MEMORY:SzHeapAlloc ERROR: sza->side %d\n", tp->nextSide); + return NULL; + } + + // Switch sides for next time in case both entries are + // SOUND_LOAD_STATUS_DISCARDABLE. + tp->nextSide ^= 1; + + return ret; + } + + ret = soundAlloc(&arg0->persistent.pool, arg1 * size); + arg0->persistent.entries[arg0->persistent.numEntries].ptr = ret; + + if (ret == NULL) + { + switch (arg3) { + case 2: + eu_stubbed_printf_0("MEMORY:StayHeap OVERFLOW."); + return alloc_bank_or_seq(arg0, arg1, size, 0, id); + case 1: + eu_stubbed_printf_1("MEMORY:StayHeap OVERFLOW (REQ:%d)", arg1 * size); + return NULL; + } + } + + // TODO: why is this guaranteed to write <= 32 entries...? + // Because the buffer is small enough that more don't fit? + arg0->persistent.entries[arg0->persistent.numEntries].id = id; + arg0->persistent.entries[arg0->persistent.numEntries].size = size; + return arg0->persistent.entries[arg0->persistent.numEntries++].ptr; +} + +void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) { + u32 i; + UNUSED void *ret; + struct TemporaryPool *temporary = &arg0->temporary; + + if (arg1 == 0) { + // Try not to overwrite sound that we have just accessed, by setting nextSide appropriately. + if (temporary->entries[0].id == id) { + temporary->nextSide = 1; + return temporary->entries[0].ptr; + } else if (temporary->entries[1].id == id) { + temporary->nextSide = 0; + return temporary->entries[1].ptr; + } + eu_stubbed_printf_1("Auto Heap Unhit for ID %d\n", id); + return NULL; + } else { + struct PersistentPool *persistent = &arg0->persistent; + for (i = 0; i < persistent->numEntries; i++) { + if (id == persistent->entries[i].id) { + eu_stubbed_printf_2("Cache hit %d at stay %d\n", id, i); + return persistent->entries[i].ptr; + } + } + + if (arg1 == 2) { + return get_bank_or_seq(arg0, 0, id); + } + return NULL; + } +} + +void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) { + s32 i; + f32 tmp[16]; + + tmp[0] = (f32) (arg1 * 262159.0f); + tmp[8] = (f32) (arg0 * 262159.0f); + tmp[1] = (f32) ((arg1 * arg0) * 262159.0f); + tmp[9] = (f32) (((arg0 * arg0) + arg1) * 262159.0f); + + for (i = 2; i < 8; i++) { + //! @bug they probably meant to store the value to tmp[i] and tmp[8 + i] + arg2[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1]; + arg2[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i]; + } + + for (i = 0; i < 16; i++) { + arg2[i] = tmp[i]; + } + + for (i = 0; i < 8; i++) { + eu_stubbed_printf_1("%d ", arg2[i]); + } + eu_stubbed_printf_0("\n"); + + for (i = 8; i < 16; i++) { + eu_stubbed_printf_1("%d ", arg2[i]); + } + eu_stubbed_printf_0("\n"); +} + +void decrease_reverb_gain(void) { + s32 i; + for (i = 0; i < gNumSynthesisReverbs; i++) { + gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 8; + } +} + + +s32 audio_shut_down_and_reset_step(void) { + s32 i; + s32 j; + + switch (gAudioResetStatus) { + case 5: + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + sequence_player_disable(&gSequencePlayers[i]); + } + gAudioResetFadeOutFramesLeft = 4; + gAudioResetStatus--; + break; + case 4: + if (gAudioResetFadeOutFramesLeft != 0) { + gAudioResetFadeOutFramesLeft--; + decrease_reverb_gain(); + } else { + for (i = 0; i < gMaxSimultaneousNotes; i++) { + if (gNotes[i].noteSubEu.enabled && gNotes[i].adsr.state != ADSR_STATE_DISABLED) { + gNotes[i].adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + gNotes[i].adsr.action |= ADSR_ACTION_RELEASE; + } + } + gAudioResetFadeOutFramesLeft = 16; + gAudioResetStatus--; + } + break; + case 3: + if (gAudioResetFadeOutFramesLeft != 0) { + gAudioResetFadeOutFramesLeft--; + decrease_reverb_gain(); + } else { + for (i = 0; i < NUMAIBUFFERS; i++) { + for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { + gAiBuffers[i][j] = 0; + } + } + gAudioResetFadeOutFramesLeft = 4; + gAudioResetStatus--; + } + break; + case 2: + if (gAudioResetFadeOutFramesLeft != 0) { + gAudioResetFadeOutFramesLeft--; + } else { + gAudioResetStatus--; + } + break; + case 1: + audio_reset_session(); + gAudioResetStatus = 0; + } + if (gAudioResetStatus < 3) { + return 0; + } + return 1; +} + +void audio_reset_session(void) { + struct AudioSessionSettingsEU *preset = &gAudioSessionPresets[gAudioResetPresetIdToLoad]; + struct ReverbSettingsEU *reverbSettings; + s16 *mem; + s32 i; + s32 j; + s32 persistentMem; + s32 temporaryMem; + s32 totalMem; + s32 wantMisc; + struct SynthesisReverb *reverb; + eu_stubbed_printf_1("Heap Reconstruct Start %x\n", gAudioResetPresetIdToLoad); + + gSampleDmaNumListItems = 0; + gAudioBufferParameters.frequency = preset->frequency; + gAudioBufferParameters.aiFrequency = osAiSetFrequency(gAudioBufferParameters.frequency); + gAudioBufferParameters.samplesPerFrameTarget = ALIGN16(gAudioBufferParameters.frequency / gRefreshRate); + gAudioBufferParameters.minAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget - 0x10; + gAudioBufferParameters.maxAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget + 0x10; + gAudioBufferParameters.updatesPerFrame = (gAudioBufferParameters.samplesPerFrameTarget + 0x10) / 160 + 1; + gAudioBufferParameters.samplesPerUpdate = (gAudioBufferParameters.samplesPerFrameTarget / gAudioBufferParameters.updatesPerFrame) & 0xfff8; + gAudioBufferParameters.samplesPerUpdateMax = gAudioBufferParameters.samplesPerUpdate + 8; + gAudioBufferParameters.samplesPerUpdateMin = gAudioBufferParameters.samplesPerUpdate - 8; + gAudioBufferParameters.resampleRate = 32000.0f / FLOAT_CAST(gAudioBufferParameters.frequency); + gAudioBufferParameters.unkUpdatesPerFrameScaled = (3.0f / 1280.0f) / gAudioBufferParameters.updatesPerFrame; + gAudioBufferParameters.updatesPerFrameInv = 1.0f / gAudioBufferParameters.updatesPerFrame; + + gMaxSimultaneousNotes = preset->maxSimultaneousNotes; + gVolume = preset->volume; + gTempoInternalToExternal = (u32) (gAudioBufferParameters.updatesPerFrame * 2880000.0f / gTatumsPerBeat / D_EU_802298D0); + + gAudioBufferParameters.presetUnk4 = preset->unk1; + gAudioBufferParameters.samplesPerFrameTarget *= gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.maxAiBufferLength *= gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.minAiBufferLength *= gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.updatesPerFrame *= gAudioBufferParameters.presetUnk4; + + gMaxAudioCmds = gMaxSimultaneousNotes * 0x10 * gAudioBufferParameters.updatesPerFrame + preset->numReverbs * 0x20 + 0x300; + + persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem + preset->persistentBankMem); + temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem + preset->temporaryBankMem); + totalMem = persistentMem + temporaryMem; + wantMisc = gAudioSessionPool.size - totalMem - 0x100; + sSessionPoolSplit.wantSeq = wantMisc; + sSessionPoolSplit.wantCustom = totalMem; + session_pools_init(&sSessionPoolSplit); + sSeqAndBankPoolSplit.wantPersistent = persistentMem; + sSeqAndBankPoolSplit.wantTemporary = temporaryMem; + seq_and_bank_pool_init(&sSeqAndBankPoolSplit); + sPersistentCommonPoolSplit.wantSeq = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem); + sPersistentCommonPoolSplit.wantBank = DOUBLE_SIZE_ON_64_BIT(preset->persistentBankMem); + sPersistentCommonPoolSplit.wantUnused = 0; + persistent_pools_init(&sPersistentCommonPoolSplit); + sTemporaryCommonPoolSplit.wantSeq = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem); + sTemporaryCommonPoolSplit.wantBank = DOUBLE_SIZE_ON_64_BIT(preset->temporaryBankMem); + sTemporaryCommonPoolSplit.wantUnused = 0; + temporary_pools_init(&sTemporaryCommonPoolSplit); + reset_bank_and_seq_load_status(); + + gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * sizeof(struct Note)); + note_init_all(); + init_note_free_list(); + + gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, (gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes) * sizeof(struct NoteSubEu)); + + for (j = 0; j != 2; j++) { + gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64)); + } + + for (j = 0; j < 4; j++) { + gSynthesisReverbs[j].useReverb = 0; + } + gNumSynthesisReverbs = preset->numReverbs; + for (j = 0; j < gNumSynthesisReverbs; j++) { + reverb = &gSynthesisReverbs[j]; + reverbSettings = &preset->reverbSettings[j]; + reverb->windowSize = reverbSettings->windowSize * 64; + reverb->downsampleRate = reverbSettings->downsampleRate; + reverb->reverbGain = reverbSettings->gain; + reverb->useReverb = 8; + reverb->ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2); + reverb->ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2); + reverb->nextRingBufferPos = 0; + reverb->unkC = 0; + reverb->curFrame = 0; + reverb->bufSizePerChannel = reverb->windowSize; + reverb->framesLeftToIgnore = 2; + if (reverb->downsampleRate != 1) { + reverb->resampleFlags = A_INIT; + reverb->resampleRate = 0x8000 / reverb->downsampleRate; + reverb->resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + reverb->resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + reverb->unk24 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + reverb->unk28 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + for (i = 0; i < gAudioBufferParameters.updatesPerFrame; i++) { + mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); + reverb->items[0][i].toDownsampleLeft = mem; + reverb->items[0][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); + mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); + reverb->items[1][i].toDownsampleLeft = mem; + reverb->items[1][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); + } + } + } + + init_sample_dma_buffers(gMaxSimultaneousNotes); + + build_vol_rampings_table(0, gAudioBufferParameters.samplesPerUpdate); + + osWritebackDCacheAll(); +} + +u8 audioString22[] = "SFrame Sample %d %d %d\n"; +u8 audioString23[] = "AHPBASE %x\n"; +u8 audioString24[] = "AHPCUR %x\n"; +u8 audioString25[] = "HeapTop %x\n"; +u8 audioString26[] = "SynoutRate %d / %d \n"; +u8 audioString27[] = "FXSIZE %d\n"; +u8 audioString28[] = "FXCOMP %d\n"; +u8 audioString29[] = "FXDOWN %d\n"; +u8 audioString30[] = "WaveCacheLen: %d\n"; +u8 audioString31[] = "SpecChange Finished\n"; diff --git a/src/audio/eu/heap.h b/src/audio/eu/heap.h new file mode 100644 index 00000000..9461151b --- /dev/null +++ b/src/audio/eu/heap.h @@ -0,0 +1,97 @@ +#ifndef AUDIO_HEAP_H +#define AUDIO_HEAP_H + +#include + +#include "internal.h" + +#define SOUND_LOAD_STATUS_NOT_LOADED 0 +#define SOUND_LOAD_STATUS_IN_PROGRESS 1 +#define SOUND_LOAD_STATUS_COMPLETE 2 +#define SOUND_LOAD_STATUS_DISCARDABLE 3 +#define SOUND_LOAD_STATUS_4 4 +#define SOUND_LOAD_STATUS_5 5 + +#define IS_BANK_LOAD_COMPLETE(bankId) (gBankLoadStatus[bankId] >= SOUND_LOAD_STATUS_COMPLETE) +#define IS_SEQ_LOAD_COMPLETE(seqId) (gSeqLoadStatus[seqId] >= SOUND_LOAD_STATUS_COMPLETE) + +struct SoundAllocPool { + u8 *start; + u8 *cur; + u32 size; + s32 numAllocatedEntries; +}; // size = 0x10 + +struct SeqOrBankEntry { + u8 *ptr; + u32 size; + s32 id; // seqId or bankId +}; // size = 0xC + +struct PersistentPool { + /*0x00*/ u32 numEntries; + /*0x04*/ struct SoundAllocPool pool; + /*0x14*/ struct SeqOrBankEntry entries[32]; +}; // size = 0x194 + +struct TemporaryPool { + /*0x00*/ u32 nextSide; + /*0x04*/ struct SoundAllocPool pool; + /*0x14*/ struct SeqOrBankEntry entries[2]; +}; // size = 0x2C + +struct SoundMultiPool { + /*0x000*/ struct PersistentPool persistent; + /*0x194*/ struct TemporaryPool temporary; + /* */ u32 pad2[4]; +}; // size = 0x1D0 + +struct Unk1Pool { + struct SoundAllocPool pool; + struct SeqOrBankEntry entries[32]; +}; + +struct UnkEntry { + s8 used; + s8 medium; + s8 bankId; + u32 pad; + u8 *srcAddr; + u8 *dstAddr; + u32 size; +}; + +struct UnkPool { + /*0x00*/ struct SoundAllocPool pool; + /*0x10*/ struct UnkEntry entries[64]; + /*0x510*/ s32 numEntries; + /*0x514*/ u32 unk514; +}; + +extern u8 gAudioHeap[]; +extern s16 gVolume; +extern s8 gReverbDownsampleRate; +extern struct SoundAllocPool gAudioInitPool; +extern struct SoundAllocPool gNotesAndBuffersPool; +extern struct SoundAllocPool gPersistentCommonPool; +extern struct SoundAllocPool gTemporaryCommonPool; +extern struct SoundMultiPool gSeqLoadedPool; +extern struct SoundMultiPool gBankLoadedPool; +extern u8 gBankLoadStatus[64]; +extern u8 gSeqLoadStatus[256]; +extern volatile u8 gAudioResetStatus; +extern u8 gAudioResetPresetIdToLoad; + +extern volatile u8 gAudioResetStatus; + +void *soundAlloc(struct SoundAllocPool *pool, u32 size); +void *sound_alloc_uninitialized(struct SoundAllocPool *pool, u32 size); +void sound_init_main_pools(s32 sizeForAudioInitPool); +void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size); +void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id); +void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id); +s32 audio_shut_down_and_reset_step(void); +void audio_reset_session(void); +void discard_bank(s32 bankId); + +#endif // AUDIO_HEAP_H diff --git a/src/audio/eu/internal.h b/src/audio/eu/internal.h new file mode 100644 index 00000000..01828927 --- /dev/null +++ b/src/audio/eu/internal.h @@ -0,0 +1,543 @@ +#ifndef AUDIO_INTERNAL_H +#define AUDIO_INTERNAL_H + +#include + +#include "types.h" + +#define SEQUENCE_PLAYERS 4 +#define SEQUENCE_CHANNELS 48 +#define SEQUENCE_LAYERS 64 + +#define LAYERS_MAX 4 +#define CHANNELS_MAX 16 + +#define NO_LAYER ((struct SequenceChannelLayer *)(-1)) + +#define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts +#define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing +#define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half + +#define SEQUENCE_PLAYER_STATE_0 0 +#define SEQUENCE_PLAYER_STATE_FADE_OUT 1 +#define SEQUENCE_PLAYER_STATE_2 2 +#define SEQUENCE_PLAYER_STATE_3 3 +#define SEQUENCE_PLAYER_STATE_4 4 + +#define NOTE_PRIORITY_DISABLED 0 +#define NOTE_PRIORITY_STOPPING 1 +#define NOTE_PRIORITY_MIN 2 +#define NOTE_PRIORITY_DEFAULT 3 + +#define TATUMS_PER_BEAT 48 + +// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing +#define CODEC_ADPCM 0 +#define CODEC_S8 1 +#define CODEC_SKIP 2 + +#define TEMPO_SCALE TATUMS_PER_BEAT + +#define JP_DOUBLE(x) x ## f + +// Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion, +// resulting in more bloated codegen, while on later versions it goes through s32. +// Since u8 and u16 fit losslessly in both, behavior is the same. +#define FLOAT_CAST(x) (f32) (s32) (x) + +// No-op printf macro which leaves string literals in rodata in IDO. IDO +// doesn't support variadic macros, so instead we let the parameter list +// expand to a no-op comma expression. Another possibility is that it might +// have expanded to something with "if (0)". See also goddard/gd_main.h. +// On US/JP, -sopt optimizes away these except for external.c. +#ifdef __sgi +#define stubbed_printf +#else +#define stubbed_printf(...) +#endif + +#define eu_stubbed_printf_0(msg) stubbed_printf(msg) +#define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a) +#define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b) +#define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c) + +struct NotePool; + +struct AudioListItem { + // A node in a circularly linked list. Each node is either a head or an item: + // - Items can be either detached (prev = NULL), or attached to a list. + // 'value' points to something of interest. + // - List heads are always attached; if a list is empty, its head points + // to itself. 'count' contains the size of the list. + // If the list holds notes, 'pool' points back to the pool where it lives. + // Otherwise, that member is NULL. + struct AudioListItem *prev; + struct AudioListItem *next; + union { + void *value; // either Note* or SequenceChannelLayer* + s32 count; + } u; + struct NotePool *pool; +}; // size = 0x10 + +struct NotePool { + struct AudioListItem disabled; + struct AudioListItem decaying; + struct AudioListItem releasing; + struct AudioListItem active; +}; + +struct VibratoState { + /*0x00*/ struct SequenceChannel *seqChannel; + /*0x04*/ u32 time; + /*0x08*/ s16 *curve; + /*0x0C*/ f32 extent; + /*0x10*/ f32 rate; + /*0x14*/ u8 active; + /*0x16*/ u16 rateChangeTimer; + /*0x18*/ u16 extentChangeTimer; + /*0x1A*/ u16 delay; +}; // size = 0x1C + +// Pitch sliding by up to one octave in the positive direction. Negative +// direction is "supported" by setting extent to be negative. The code +// extrapolates exponentially in the wrong direction in that case, but that +// doesn't prevent seqplayer from doing it, AFAICT. +struct Portamento { + u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 + f32 cur; + f32 speed; + f32 extent; +}; // size = 0x10 + +struct AdsrEnvelope { + s16 delay; + s16 arg; +}; // size = 0x4 + +struct AdpcmLoop { + u32 start; + u32 end; + u32 count; + u32 pad; + s16 state[16]; // only exists if count != 0. 8-byte aligned +}; + +struct AdpcmBook { + s32 order; + s32 npredictors; + s16 book[1]; // size 8 * order * npredictors. 8-byte aligned +}; + +struct AudioBankSample { + u8 unused; + u8 loaded; + u8 *sampleAddr; + struct AdpcmLoop *loop; + struct AdpcmBook *book; + u32 sampleSize; // never read. either 0 or 1 mod 9, depending on padding +}; + +struct AudioBankSound { + struct AudioBankSample *sample; + f32 tuning; // frequency scale factor +}; // size = 0x8 + +struct Instrument { + /*0x00*/ u8 loaded; + /*0x01*/ u8 normalRangeLo; + /*0x02*/ u8 normalRangeHi; + /*0x03*/ u8 releaseRate; + /*0x04*/ struct AdsrEnvelope *envelope; + /*0x08*/ struct AudioBankSound lowNotesSound; + /*0x10*/ struct AudioBankSound normalNotesSound; + /*0x18*/ struct AudioBankSound highNotesSound; +}; // size = 0x20 + +struct Drum { + u8 releaseRate; + u8 pan; + u8 loaded; + struct AudioBankSound sound; + struct AdsrEnvelope *envelope; +}; + +struct AudioBank { + struct Drum **drums; + struct Instrument *instruments[1]; +}; // dynamic size + +struct CtlEntry { + u8 unused; + u8 numInstruments; + u8 numDrums; + struct Instrument **instruments; + struct Drum **drums; +}; // size = 0xC + +struct M64ScriptState { + u8 *pc; + u8 *stack[4]; + u8 remLoopIters[4]; + u8 depth; +}; // size = 0x1C + +// Also known as a Group, according to debug strings. +struct SequencePlayer { + /*0x000*/ u8 enabled : 1; + /*0x000*/ u8 finished : 1; // never read + /*0x000*/ u8 muted : 1; + /*0x000*/ u8 seqDmaInProgress : 1; + /*0x000*/ u8 bankDmaInProgress : 1; + /*0x000*/ u8 recalculateVolume : 1; + /*0x001*/ u8 state; + /*0x002*/ u8 noteAllocPolicy; + /*0x003*/ u8 muteBehavior; + /*0x004*/ u8 seqId; + /*0x005*/ u8 defaultBank[1]; // must be an array to get a comparison + // to match; other u8's might also be part of that array + /*0x006*/ u8 loadingBankId; + /*0x007*/ s8 seqVariationEu[1]; + /*0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU + /*0x00A*/ u16 tempoAcc; + /*0x00C*/ s16 transposition; + /*0x00E*/ u16 delay; + /*0x010*/ u16 fadeRemainingFrames; + /*0x012*/ u16 fadeTimerUnkEu; + /*0x014*/ u8 *seqData; // buffer of some sort + /*0x018*/ f32 fadeVolume; // set to 1.0f + /*0x01C*/ f32 fadeVelocity; // set to 0.0f + /*0x020*/ f32 volume; // set to 0.0f + /*0x024*/ f32 muteVolumeScale; // set to 0.5f + /*0x028*/ f32 fadeVolumeScale; + /*0x02C*/ f32 appliedFadeVolume; + /*0x030*/ struct SequenceChannel *channels[CHANNELS_MAX]; + /*0x070*/ struct M64ScriptState scriptState; + /*0x08C*/ u8 *shortNoteVelocityTable; + /*0x090*/ u8 *shortNoteDurationTable; + /*0x094*/ struct NotePool notePool; + /*0x0D4*/ OSMesgQueue seqDmaMesgQueue; + /*0x0EC*/ OSMesg seqDmaMesg; + /*0x0F0*/ OSIoMesg seqDmaIoMesg; + /*0x108*/ OSMesgQueue bankDmaMesgQueue; + /*0x120*/ OSMesg bankDmaMesg; + /*0x124*/ OSIoMesg bankDmaIoMesg; + /*0x13C*/ u8 *bankDmaCurrMemAddr; + /*0x140*/ uintptr_t bankDmaCurrDevAddr; + /*0x144*/ ssize_t bankDmaRemaining; +}; // size = 0x148 + +struct AdsrSettings { + u8 releaseRate; + u8 sustain; + struct AdsrEnvelope *envelope; +}; // size = 0x8 + +struct AdsrState { + /*0x00*/ u8 action; + /*0x01*/ u8 state; + /*0x02*/ s16 envIndex; + /*0x04*/ s16 delay; + /*0x08*/ f32 sustain; + /*0x0C*/ f32 velocity; + /*0x10*/ f32 fadeOutVel; + /*0x14*/ f32 current; + /*0x18*/ f32 target; + /* */ s32 pad1C; + /*0x20*/ struct AdsrEnvelope *envelope; +}; // size = 0x24 + +struct ReverbBitsData { + /*0x00*/ u8 bit0 : 1; + /*0x00*/ u8 bit1 : 1; + /*0x00*/ u8 bit2 : 1; + /*0x00*/ u8 usesHeadsetPanEffects : 1; + /*0x00*/ u8 stereoHeadsetEffects : 2; + /*0x00*/ u8 strongRight : 1; + /*0x00*/ u8 strongLeft : 1; +}; + +union ReverbBits { + /*0x00*/ struct ReverbBitsData s; + /*0x00*/ u8 asByte; +}; +struct ReverbInfo { + u8 reverbVol; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + u8 pan; + union ReverbBits reverbBits; + f32 freqScale; + f32 velocity; + s32 unused; + s16 *filter; +}; + +struct NoteAttributes { + u8 reverbVol; + u8 pan; + f32 freqScale; + f32 velocity; +}; // size = 0x10 + +// Also known as a SubTrack, according to debug strings. +// Confusingly, a SubTrack is a container of Tracks. +struct SequenceChannel { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 stopScript : 1; + /*0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething + /*0x00*/ u8 hasInstrument : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*????*/ u8 largeNotes : 1; // notes specify duration and velocity + /*????*/ u8 unused : 1; // never read, set to 0 + /*0x01*/ union { + struct { + u8 freqScale : 1; + u8 volume : 1; + u8 pan : 1; + } as_bitfields; + u8 as_u8; + } changes; + /*0x02*/ u8 noteAllocPolicy; + /*0x03*/ u8 muteBehavior; + /*0x04*/ u8 reverbVol; // until EU: Q1.7, after EU: UQ0.8 + /*????*/ u8 notePriority; // 0-3 + /*0x06*/ u8 bankId; + /*0x07*/ u8 reverbIndex; + /*0x08*/ u8 bookOffset; + /*0x09*/ u8 newPan; + /*0x0A*/ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128) + /*0x0C*/ u16 vibratoRateStart; // initially 0x800 + /*0x0E*/ u16 vibratoExtentStart; + /*0x10*/ u16 vibratoRateTarget; // initially 0x800 + /*0x12*/ u16 vibratoExtentTarget; + /*0x14*/ u16 vibratoRateChangeDelay; + /*0x16*/ u16 vibratoExtentChangeDelay; + /*0x18*/ u16 vibratoDelay; + /*0x1A*/ u16 delay; + /*0x1C*/ s16 instOrWave; // either 0 (none), instrument index + 1, or + // 0x80..0x83 for sawtooth/triangle/sine/square waves. + /*0x1E*/ s16 transposition; + /*0x20*/ f32 volumeScale; + /*0x24*/ f32 volume; + /*0x28*/ s32 pan; + /*0x2C*/ f32 appliedVolume; + /*0x30*/ f32 freqScale; + /*0x34*/ u8 (*dynTable)[][2]; + /*????*/ struct Note *noteUnused; // never read + /*????*/ struct SequenceChannelLayer *layerUnused; // never read + /*0x40*/ struct Instrument *instrument; + /*0x44*/ struct SequencePlayer *seqPlayer; + /*0x48*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; + /*0x58*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, + // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment + /*0x60*/ struct M64ScriptState scriptState; + /*0x7C*/ struct AdsrSettings adsr; + /*0x84*/ struct NotePool notePool; +}; // size = 0xC4 + +// Also known as a Track, according to debug strings. +struct SequenceChannelLayer { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 stopSomething : 1; // ? + /*0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound + /*0x00*/ u8 unusedEu0b8 : 1; + /*0x00*/ u8 notePropertiesNeedInit : 1; + /*0x00*/ u8 ignoreDrumPan : 1; + /*0x01*/ u8 instOrWave; + /*0x02*/ u8 status; + /*0x03*/ u8 noteDuration; // set to 0x80 + /*0x04*/ u8 portamentoTargetNote; + /*0x05*/ u8 pan; // 0..128 + /*0x06*/ u8 notePan; + /*0x08*/ struct Portamento portamento; + /*0x18*/ struct AdsrSettings adsr; + /*0x20*/ u16 portamentoTime; + /*0x22*/ s16 transposition; // #semitones added to play commands + // (m64 instruction encoding only allows referring to the limited range + // 0..0x3f; this makes 0x40..0x7f accessible as well) + /*0x24*/ f32 freqScale; + /*0x28*/ f32 velocitySquare; + /*0x2C*/ f32 noteVelocity; + /*0x30*/ f32 noteFreqScale; + /*0x34*/ s16 shortNoteDefaultPlayPercentage; + /*0x36*/ s16 playPercentage; // it's not really a percentage... + /*0x38*/ s16 delay; + /*0x3A*/ s16 duration; + /*0x3C*/ s16 delayUnused; // set to 'delay', never read + /*0x40*/ struct Note *note; + /*0x44*/ struct Instrument *instrument; + /*0x48*/ struct AudioBankSound *sound; + /*0x4C*/ struct SequenceChannel *seqChannel; + /*0x50*/ struct M64ScriptState scriptState; + /*0x6C*/ struct AudioListItem listItem; + /* */ u8 pad2[4]; +}; // size = 0x80 + +struct NoteSynthesisState { + /*0x00*/ u8 restart; + /*0x01*/ u8 sampleDmaIndex; + /*0x02*/ u8 prevHeadsetPanRight; + /*0x03*/ u8 prevHeadsetPanLeft; + /*0x04*/ u16 samplePosFrac; + /*0x08*/ s32 samplePosInt; + /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; + /*0x10*/ s16 curVolLeft; // UQ0.16 (EU Q1.15) + /*0x12*/ s16 curVolRight; // UQ0.16 (EU Q1.15) +}; +struct NotePlaybackState { + /*0x00*/ u8 priority; + /*0x01*/ u8 waveId; + /*0x02*/ u8 sampleCountIndex; + /*0x04*/ s16 adsrVolScale; + /*0x08*/ f32 portamentoFreqScale; + /*0x0C*/ f32 vibratoFreqScale; + /*0x10*/ struct SequenceChannelLayer *prevParentLayer; + /*0x14*/ struct SequenceChannelLayer *parentLayer; + /*0x18*/ struct SequenceChannelLayer *wantedParentLayer; + /*0x1C*/ struct NoteAttributes attributes; + /*0x28*/ struct AdsrState adsr; + /*0x4C*/ struct Portamento portamento; + /*0x5C*/ struct VibratoState vibratoState; +}; +struct NoteSubEu { + /*0x00*/ volatile u8 enabled : 1; + /*0x00*/ u8 needsInit : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 envMixerNeedsInit : 1; + /*0x00*/ u8 stereoStrongRight : 1; + /*0x00*/ u8 stereoStrongLeft : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00*/ u8 usesHeadsetPanEffects : 1; + /*0x01*/ u8 reverbIndex : 3; + /*0x01*/ u8 bookOffset : 3; + /*0x01*/ u8 isSyntheticWave : 1; + /*0x01*/ u8 hasTwoAdpcmParts : 1; + /*0x02*/ u8 bankId; + /*0x03*/ u8 headsetPanRight; + /*0x04*/ u8 headsetPanLeft; + /*0x05*/ u8 reverbVol; // UQ0.7 (EU Q1.7) + /*0x06*/ u16 targetVolLeft; // UQ0.12 (EU UQ0.10) + /*0x08*/ u16 targetVolRight; // UQ0.12 (EU UQ0.10) + /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 + /*0x0C*/ union { + s16 *samples; + struct AudioBankSound *audioBankSound; + } sound; +}; +struct Note { + /*0x00*/ struct AudioListItem listItem; + /*0x10*/ struct NoteSynthesisState synthesisState; + // The next members are actually part of a struct (NotePlaybackState), but + // that results in messy US/EU ifdefs. Instead we cast to a struct pointer + // when needed... This breaks alignment on non-N64 platforms, which we hack + // around by skipping the padding in that case. + // TODO: use macros or something instead. +#ifdef TARGET_N64 + u8 pad0[12]; +#endif + + /*0x30*/ u8 priority; + /*0x31*/ u8 waveId; + /*0x32*/ u8 sampleCountIndex; + /*0x34*/ s16 adsrVolScale; + /*0x38*/ f32 portamentoFreqScale; + /*0x3C*/ f32 vibratoFreqScale; + /*0x40*/ struct SequenceChannelLayer *prevParentLayer; + /*0x44*/ struct SequenceChannelLayer *parentLayer; + /*0x48*/ struct SequenceChannelLayer *wantedParentLayer; + /*0x4C*/ struct NoteAttributes attributes; + /*0x58*/ struct AdsrState adsr; + /*0x7C*/ struct Portamento portamento; + /*0x8C*/ struct VibratoState vibratoState; + /* */ u8 pad3[8]; + /*0xB0*/ struct NoteSubEu noteSubEu; +}; // size = 0xC0 + +struct NoteSynthesisBuffers { + s16 adpcmdecState[0x10]; + s16 finalResampleState[0x10]; + s16 mixEnvelopeState[0x28]; + s16 panResampleState[0x10]; + s16 panSamplesBuffer[0x20]; + s16 dummyResampleState[0x10]; +}; + +struct ReverbSettingsEU { + u8 downsampleRate; + u8 windowSize; // To be multiplied by 64 + u16 gain; +}; + +struct AudioSessionSettingsEU { + /*0x00*/ u32 frequency; + /*0x04*/ u8 unk1; // always 1 + /*0x05*/ u8 maxSimultaneousNotes; + /*0x06*/ u8 numReverbs; // always 1 + /*0x07*/ u8 unk2; // always 0 + /*0x08*/ struct ReverbSettingsEU *reverbSettings; + /*0x0C*/ u16 volume; + /*0x0E*/ u16 unk3; // always 0 + /*0x10*/ u32 persistentSeqMem; + /*0x14*/ u32 persistentBankMem; + /*0x18*/ u32 temporarySeqMem; + /*0x1C*/ u32 temporaryBankMem; +}; // size = 0x20 + +struct AudioBufferParametersEU { + /*0x00*/ s16 presetUnk4; // audio frames per vsync? + /*0x02*/ u16 frequency; + /*0x04*/ u16 aiFrequency; // ?16 + /*0x06*/ s16 samplesPerFrameTarget; + /*0x08*/ s16 maxAiBufferLength; + /*0x0A*/ s16 minAiBufferLength; + /*0x0C*/ s16 updatesPerFrame; + /*0x0E*/ s16 samplesPerUpdate; + /*0x10*/ s16 samplesPerUpdateMax; + /*0x12*/ s16 samplesPerUpdateMin; + /*0x14*/ f32 resampleRate; // contains 32000.0f / frequency + /*0x18*/ f32 updatesPerFrameInv; // 1.0f / updatesPerFrame + /*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame) +}; + +struct EuAudioCmd { + union { +#if IS_BIG_ENDIAN + struct { + u8 op; + u8 arg1; + u8 arg2; + u8 arg3; + } s; +#else + struct { + u8 arg3; + u8 arg2; + u8 arg1; + u8 op; + } s; +#endif + s32 first; + } u; + union { + s32 as_s32; + u32 as_u32; + f32 as_f32; +#if IS_BIG_ENDIAN + u8 as_u8; + s8 as_s8; +#else + struct { + u8 pad0[3]; + u8 as_u8; + }; + struct { + u8 pad1[3]; + s8 as_s8; + }; +#endif + } u2; +}; + +#endif // AUDIO_INTERNAL_H diff --git a/src/audio/eu/load.c b/src/audio/eu/load.c new file mode 100644 index 00000000..4cbbc39e --- /dev/null +++ b/src/audio/eu/load.c @@ -0,0 +1,823 @@ +#include +#include + +#include "data.h" +#include "heap.h" +#include "load.h" +#include "seqplayer.h" + +#define ALIGN16(val) (((val) + 0xF) & ~0xF) + +struct SharedDma { + /*0x0*/ u8 *buffer; // target, points to pre-allocated buffer + /*0x4*/ uintptr_t source; // device address + /*0x8*/ u16 sizeUnused; // set to bufSize, never read + /*0xA*/ u16 bufSize; // size of buffer + /*0xC*/ u8 unused2; // set to 0, never read + /*0xD*/ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0 + /*0xE*/ u8 ttl; // duration after which the DMA can be discarded +}; // size = 0x10 + +void port_eu_init(void); + +struct Note *gNotes; + +UNUSED static u8 pad[4]; + +struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; +struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; + +struct SequenceChannel gSequenceChannelNone; +struct AudioListItem gLayerFreeList; +struct NotePool gNoteFreeLists; + +OSMesgQueue gCurrAudioFrameDmaQueue; +OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; +OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; + +OSMesgQueue gAudioDmaMesgQueue; +OSMesg gAudioDmaMesg; +OSIoMesg gAudioDmaIoMesg; + +struct SharedDma sSampleDmas[0x60]; +u32 gSampleDmaNumListItems; +u32 sSampleDmaListSize1; +u32 sUnused80226B40; // set to 0, never read + +// Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256. +u8 sSampleDmaReuseQueue1[256]; +u8 sSampleDmaReuseQueue2[256]; +u8 sSampleDmaReuseQueueTail1; +u8 sSampleDmaReuseQueueTail2; +u8 sSampleDmaReuseQueueHead1; +u8 sSampleDmaReuseQueueHead2; + +ALSeqFile *gSeqFileHeader; +ALSeqFile *gAlCtlHeader; +ALSeqFile *gAlTbl; +u8 *gAlBankSets; +u16 gSequenceCount; + +struct CtlEntry *gCtlEntries; + +u32 padEuBss1; +struct AudioBufferParametersEU gAudioBufferParameters; + +u32 sDmaBufSize; +s32 gMaxAudioCmds; +s32 gMaxSimultaneousNotes; + +s16 gTempoInternalToExternal; + +s8 gSoundMode; + +s8 gAudioUpdatesPerFrame; + +extern u64 gAudioGlobalsStartMarker; +extern u64 gAudioGlobalsEndMarker; + +extern u8 gSoundDataADSR[]; // sound_data.ctl +extern u8 gSoundDataRaw[]; // sound_data.tbl +extern u8 gMusicData[]; // sequences.s +extern u8 gBankSetsData[]; // bank_sets.s + +ALSeqFile *get_audio_file_header(s32 arg0); + +/** + * Performs an immediate DMA copy + */ +void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { + eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes); + osInvalDCache(vAddr, nbytes); + osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes, + &gAudioDmaMesgQueue); + osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK); + eu_stubbed_printf_0("Romcopyend\n"); +} + +u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d"; +u8 audioString35[] = "BASE %x %x\n"; +u8 audioString36[] = "LOAD %x %x %x\n"; +u8 audioString37[] = "INSTTOP %x\n"; +u8 audioString38[] = "INSTMAP[0] %x\n"; +u8 audioString39[] = "already flags %d\n"; +u8 audioString40[] = "already flags %d\n"; +u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n"; +u8 audioString42[] = "ERR:SLOW DMA BUSY\n"; +u8 audioString43[] = "Check %d bank %d\n"; +u8 audioString44[] = "Cache Check\n"; +u8 audioString45[] = "NO BANK ERROR\n"; +u8 audioString46[] = "BANK %d LOADING START\n"; +u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n"; +u8 audioString48[] = "BANK %d ALREADY CACHED\n"; +u8 audioString49[] = "BANK LOAD MISS! FOR %d\n"; + +/** + * Performs an asynchronus (normal priority) DMA copy + */ +void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *queue, OSIoMesg *mesg) { + osInvalDCache(vAddr, nbytes); + osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vAddr, nbytes, queue); +} + +/** + * Performs a partial asynchronous (normal priority) DMA copy. This is limited + * to 0x1000 bytes transfer at once. + */ +void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { + ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining); + *remaining -= transfer; + osInvalDCache(*vAddr, transfer); + osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, *devAddr, *vAddr, transfer, queue); + *devAddr += transfer; + *vAddr += transfer; +} + +void decrease_sample_dma_ttls() { + u32 i; + + for (i = 0; i < sSampleDmaListSize1; i++) { + struct SharedDma *temp = &sSampleDmas[i]; + if (temp->ttl != 0) { + temp->ttl--; + if (temp->ttl == 0) { + temp->reuseIndex = sSampleDmaReuseQueueHead1; + sSampleDmaReuseQueue1[sSampleDmaReuseQueueHead1++] = (u8) i; + } + } + } + + for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { + struct SharedDma *temp = &sSampleDmas[i]; + if (temp->ttl != 0) { + temp->ttl--; + if (temp->ttl == 0) { + temp->reuseIndex = sSampleDmaReuseQueueHead2; + sSampleDmaReuseQueue2[sSampleDmaReuseQueueHead2++] = (u8) i; + } + } + } + + sUnused80226B40 = 0; +} + +void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { + s32 hasDma = FALSE; + struct SharedDma *dma; + uintptr_t dmaDevAddr; + u32 transfer; + u32 i; + u32 dmaIndex; + ssize_t bufferPos; + UNUSED u32 pad; + + if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) { + for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { + dma = &sSampleDmas[i]; + bufferPos = devAddr - dma->source; + if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { + // We already have a DMA request for this memory range. + if (dma->ttl == 0 && sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2) { + // Move the DMA out of the reuse queue, by swapping it with the + // tail, and then incrementing the tail. + if (dma->reuseIndex != sSampleDmaReuseQueueTail2) { + sSampleDmaReuseQueue2[dma->reuseIndex] = + sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]; + sSampleDmas[sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]].reuseIndex = + dma->reuseIndex; + } + sSampleDmaReuseQueueTail2++; + } + dma->ttl = 60; + *dmaIndexRef = (u8) i; + return &dma->buffer[(devAddr - dma->source)]; + } + } + + if (sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2 && arg2 != 0) { + // Allocate a DMA from reuse queue 2. This queue can be empty, since + // TTL 60 is pretty large. + dmaIndex = sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]; + sSampleDmaReuseQueueTail2++; + dma = sSampleDmas + dmaIndex; + hasDma = TRUE; + } + } else { + dma = sSampleDmas; + dma += *dmaIndexRef; + bufferPos = devAddr - dma->source; + if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { + // We already have DMA for this memory range. + if (dma->ttl == 0) { + // Move the DMA out of the reuse queue, by swapping it with the + // tail, and then incrementing the tail. + if (dma->reuseIndex != sSampleDmaReuseQueueTail1) { + if (1) { + } + sSampleDmaReuseQueue1[dma->reuseIndex] = + sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]; + sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex = + dma->reuseIndex; + } + sSampleDmaReuseQueueTail1++; + } + dma->ttl = 2; + return dma->buffer + (devAddr - dma->source); + } + } + + if (!hasDma) { + // Allocate a DMA from reuse queue 1. This queue will hopefully never + // be empty, since TTL 2 is so small. + dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++]; + dma = sSampleDmas + dmaIndex; + hasDma = TRUE; + } + + transfer = dma->bufSize; + dmaDevAddr = devAddr & ~0xF; + dma->ttl = 2; + dma->source = dmaDevAddr; + dma->sizeUnused = transfer; + osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, + OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); + *dmaIndexRef = dmaIndex; + return (devAddr - dmaDevAddr) + dma->buffer; +} + + +void init_sample_dma_buffers(UNUSED s32 arg0) { + s32 i; + + sDmaBufSize = 0x400; + + for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) + { + sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); + if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { + break; + } + sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; + sSampleDmas[gSampleDmaNumListItems].source = 0; + sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; + sSampleDmas[gSampleDmaNumListItems].unused2 = 0; + sSampleDmas[gSampleDmaNumListItems].ttl = 0; + gSampleDmaNumListItems++; + } + + for (i = 0; (u32) i < gSampleDmaNumListItems; i++) { + sSampleDmaReuseQueue1[i] = (u8) i; + sSampleDmas[i].reuseIndex = (u8) i; + } + + for (i = gSampleDmaNumListItems; i < 0x100; i++) { + sSampleDmaReuseQueue1[i] = 0; + } + + sSampleDmaReuseQueueTail1 = 0; + sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems; + sSampleDmaListSize1 = gSampleDmaNumListItems; + + sDmaBufSize = 0x200; + for (i = 0; i < gMaxSimultaneousNotes; i++) { + sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); + if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { + break; + } + sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; + sSampleDmas[gSampleDmaNumListItems].source = 0; + sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; + sSampleDmas[gSampleDmaNumListItems].unused2 = 0; + sSampleDmas[gSampleDmaNumListItems].ttl = 0; + gSampleDmaNumListItems++; + } + + for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) { + sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i; + sSampleDmas[i].reuseIndex = (u8)(i - sSampleDmaListSize1); + } + + // This probably meant to touch the range size1..size2 as well... but it + // doesn't matter, since these values are never read anyway. + for (i = gSampleDmaNumListItems; i < 0x100; i++) { + sSampleDmaReuseQueue2[i] = sSampleDmaListSize1; + } + + sSampleDmaReuseQueueTail2 = 0; + sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1; +} + +void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED u8 *offsetBase) { + struct AudioBankSample *sample; + void *patched; + u8 *mem; + +#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) + + if (sound->sample != NULL) { + sample = sound->sample = PATCH(sound->sample, memBase); + if (sample->loaded == 0) { + sample->sampleAddr = PATCH(sample->sampleAddr, offsetBase); + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); + sample->loaded = 1; + } + else if (sample->loaded == 0x80) { + PATCH(sample->sampleAddr, offsetBase); + mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); + if (mem == NULL) { + sample->sampleAddr = patched; + sample->loaded = 1; + } else { + audio_dma_copy_immediate((uintptr_t) patched, mem, sample->sampleSize); + sample->loaded = 0x81; + sample->sampleAddr = mem; + } + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); + } + } + +#undef PATCH +} + +// on US/JP this inlines patch_sound, using some -sopt compiler flag +void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { + struct Instrument *instrument; + struct Instrument **itInstrs; + struct Instrument **end; + struct AudioBank *temp; + u32 i; + void *patched; + struct Drum *drum; + struct Drum **drums; + u32 numDrums2; + +#define BASE_OFFSET_REAL(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) +#define PATCH(x, base) (patched = BASE_OFFSET_REAL(x, base)) +#define PATCH_MEM(x) x = PATCH(x, mem) + +#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(base, x) + + drums = mem->drums; + numDrums2 = numDrums; + if (drums != NULL && numDrums2 > 0) { + mem->drums = PATCH(drums, mem); + for (i = 0; i < numDrums2; i++) { + patched = mem->drums[i]; + if (patched != NULL) { + drum = PATCH(patched, mem); + mem->drums[i] = drum; + if (drum->loaded == 0) { + patch_sound(&drum->sound, (u8 *) mem, offset); + patched = drum->envelope; + drum->envelope = BASE_OFFSET(mem, patched); + drum->loaded = 1; + } + } + } + } + + //! Doesn't affect EU, but required for US/JP + temp = &*mem; + if (numInstruments > 0) { + //! Doesn't affect EU, but required for US/JP + struct Instrument **tempInst; + itInstrs = temp->instruments; + tempInst = temp->instruments; + end = numInstruments + tempInst; + + do { + if (*itInstrs != NULL) { + *itInstrs = BASE_OFFSET(*itInstrs, mem); + instrument = *itInstrs; + + if (instrument->loaded == 0) { + patch_sound(&instrument->lowNotesSound, (u8 *) mem, offset); + patch_sound(&instrument->normalNotesSound, (u8 *) mem, offset); + patch_sound(&instrument->highNotesSound, (u8 *) mem, offset); + patched = instrument->envelope; + instrument->envelope = BASE_OFFSET(mem, patched); + instrument->loaded = 1; + } + } + itInstrs++; + } while (end != itInstrs); + } +#undef PATCH_MEM +#undef PATCH +#undef BASE_OFFSET_REAL +#undef BASE_OFFSET +} + +struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { + UNUSED u32 pad1[4]; + u32 buf[4]; + u32 numInstruments, numDrums; + struct AudioBank *ret; + u8 *ctlData; + s32 alloc; + + // (This is broken if the length is 1 (mod 16), but that never happens -- + // it's always divisible by 4.) + alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; + alloc = ALIGN16(alloc); + alloc -= 0x10; + ctlData = gAlCtlHeader->seqArray[bankId].offset; + ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId); + if (ret == NULL) { + return NULL; + } + + audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10); + numInstruments = buf[0]; + numDrums = buf[1]; + audio_dma_copy_immediate((uintptr_t)(ctlData + 0x10), ret, alloc); + patch_audio_bank(ret, gAlTbl->seqArray[bankId].offset, numInstruments, numDrums); + gCtlEntries[bankId].numInstruments = (u8) numInstruments; + gCtlEntries[bankId].numDrums = (u8) numDrums; + gCtlEntries[bankId].instruments = ret->instruments; + gCtlEntries[bankId].drums = ret->drums; + gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE; + return ret; +} + +struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *seqPlayer) { + u32 numInstruments, numDrums; + UNUSED u32 pad1[2]; + u32 buf[4]; + UNUSED u32 pad2; + size_t alloc; + struct AudioBank *ret; + u8 *ctlData; + OSMesgQueue *mesgQueue; + UNUSED u32 pad3; + + alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; + alloc = ALIGN16(alloc); + alloc -= 0x10; + ctlData = gAlCtlHeader->seqArray[bankId].offset; + ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId); + if (ret == NULL) { + return NULL; + } + + audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10); + numInstruments = buf[0]; + numDrums = buf[1]; + seqPlayer->loadingBankId = (u8) bankId; + gCtlEntries[bankId].numInstruments = numInstruments; + gCtlEntries[bankId].numDrums = numDrums; + gCtlEntries[bankId].instruments = ret->instruments; + gCtlEntries[bankId].drums = 0; + seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; + seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); + seqPlayer->bankDmaRemaining = alloc; + if (1) { + } + mesgQueue = &seqPlayer->bankDmaMesgQueue; + osCreateMesgQueue(mesgQueue, &seqPlayer->bankDmaMesg, 1); + seqPlayer->bankDmaInProgress = TRUE; + audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, + &seqPlayer->bankDmaRemaining, mesgQueue, &seqPlayer->bankDmaIoMesg); + gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_IN_PROGRESS; + return ret; +} + +void *sequence_dma_immediate(s32 seqId, s32 arg1) { + s32 seqLength; + void *ptr; + u8 *seqData; + + seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf; + seqLength = ALIGN16(seqLength); + seqData = gSeqFileHeader->seqArray[seqId].offset; + ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId); + if (ptr == NULL) { + return NULL; + } + + audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength); + gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE; + return ptr; +} + +void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) { + s32 seqLength; + void *ptr; + u8 *seqData; + OSMesgQueue *mesgQueue; + + eu_stubbed_printf_1("Seq %d Loading Start\n", seqId); + seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf; + seqLength = ALIGN16(seqLength); + seqData = gSeqFileHeader->seqArray[seqId].offset; + ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId); + if (ptr == NULL) { + eu_stubbed_printf_0("Heap Overflow Error\n"); + return NULL; + } + + if (seqLength <= 0x40) { + // Immediately load short sequenece + audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength); + if (1) { + } + gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE; + } else { + audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40); + mesgQueue = &seqPlayer->seqDmaMesgQueue; + osCreateMesgQueue(mesgQueue, &seqPlayer->seqDmaMesg, 1); + seqPlayer->seqDmaInProgress = TRUE; + audio_dma_copy_async((uintptr_t)(seqData + 0x40), (u8 *) ptr + 0x40, seqLength - 0x40, mesgQueue, + &seqPlayer->seqDmaIoMesg); + gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_IN_PROGRESS; + } + return ptr; +} + +u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { + void *temp; + u32 bankId; + u16 offset; + u8 i; + u8 ret; + + *nullCount = 0; + *nonNullCount = 0; + offset = ((u16 *) gAlBankSets)[seqId]; + for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) { + bankId = gAlBankSets[offset++]; + + if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { + temp = get_bank_or_seq(&gBankLoadedPool, 2, bankId); + } else { + temp = NULL; + } + + if (temp == NULL) { + (*nullCount)++; + ret = bankId; + } else { + (*nonNullCount)++; + } + } + + return ret; +} + +struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { + void *ret; + u32 bankId; + u16 offset; + u8 i; + + offset = ((u16 *) gAlBankSets)[seqId]; + for (i = gAlBankSets[offset++]; i != 0; i--) { + bankId = gAlBankSets[offset++]; + + if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { + ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId); + } else { + ret = NULL; + } + + if (ret == NULL) { + ret = bank_load_immediate(bankId, 2); + } + } + *outDefaultBank = bankId; + return ret; +} + +void preload_sequence(u32 seqId, u8 preloadMask) { + void *sequenceData; + u8 temp; + + if (seqId >= gSequenceCount) { + return; + } + + gAudioLoadLock = AUDIO_LOCK_LOADING; + if (preloadMask & PRELOAD_BANKS) { + load_banks_immediate(seqId, &temp); + } + + if (preloadMask & PRELOAD_SEQUENCE) { + // @bug should be IS_SEQ_LOAD_COMPLETE + if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) { + eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId); + sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); + } else { + sequenceData = NULL; + } + if (sequenceData == NULL && sequence_dma_immediate(seqId, 2) == NULL) { + gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; + return; + } + } + + gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; +} + +void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync); + +void load_sequence(u32 player, u32 seqId, s32 loadAsync) { + if (!loadAsync) { + gAudioLoadLock = AUDIO_LOCK_LOADING; + } + load_sequence_internal(player, seqId, loadAsync); + if (!loadAsync) { + gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; + } +} + +void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { + void *sequenceData; + struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; + UNUSED u32 padding[2]; + + if (seqId >= gSequenceCount) { + return; + } + + sequence_player_disable(seqPlayer); + if (loadAsync) { + s32 numMissingBanks = 0; + s32 dummy = 0; + s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks); + if (numMissingBanks == 1) { + eu_stubbed_printf_0("Ok,one bank slow load Start \n"); + if (bank_load_async(bankId, 2, seqPlayer) == NULL) { + return; + } + // @bug This should set the last bank (i.e. the first in the JSON) + // as default, not the missing one. This code path never gets + // taken, though -- all sequence loading is synchronous. + seqPlayer->defaultBank[0] = bankId; + } else { + eu_stubbed_printf_1("Sorry,too many %d bank is none.fast load Start \n", numMissingBanks); + if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { + return; + } + } + } else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { + return; + } + + eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]); + eu_stubbed_printf_0("Seq Loading Start\n"); + + seqPlayer->seqId = seqId; + sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); + if (sequenceData == NULL) { + if (seqPlayer->seqDmaInProgress) { + eu_stubbed_printf_0("Error:Before Sequence-SlowDma remain.\n"); + eu_stubbed_printf_0(" Cancel Seq Start.\n"); + return; + } + if (loadAsync) { + sequenceData = sequence_dma_async(seqId, 2, seqPlayer); + } else { + sequenceData = sequence_dma_immediate(seqId, 2); + } + + if (sequenceData == NULL) { + return; + } + } + + eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId); + init_sequence_player(player); + seqPlayer->scriptState.depth = 0; + seqPlayer->delay = 0; + seqPlayer->enabled = TRUE; + seqPlayer->seqData = sequenceData; + seqPlayer->scriptState.pc = sequenceData; +} + +// (void) must be omitted from parameters to fix stack with -framepointer +void audio_init() { + UNUSED s8 pad[20]; + s32 i, j, k; + u8 buf[0x10]; + UNUSED s32 lim3; + u32 size; + UNUSED u64 *ptr64; + void *data; + UNUSED s32 pad2[2]; + + gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; + + for (i = 0; i < gAudioHeapSize / 8; i++) { + ((u64 *) gAudioHeap)[i] = 0; + } + +#ifdef TARGET_N64 + // It seems boot.s doesn't clear the .bss area for audio, so do it here. + lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; + ptr64 = &gAudioGlobalsStartMarker; + for (k = lim3; k >= 0; k--) { + *ptr64++ = 0; + } +#endif + + D_EU_802298D0 = 20.03042f; + gRefreshRate = 50; + port_eu_init(); + if (k) { + } + +#ifdef TARGET_N64 + eu_stubbed_printf_3( + "Clear Workarea %x -%x size %x \n", + (uintptr_t) &gAudioGlobalsStartMarker, + (uintptr_t) &gAudioGlobalsEndMarker, + (uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker + ); +#endif + + eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize); + + for (i = 0; i < NUMAIBUFFERS; i++) { + gAiBufferLengths[i] = 0xa0; + } + + gAudioFrameCount = 0; + gAudioTaskIndex = 0; + gCurrAiBufferIndex = 0; + gSoundMode = 0; + gAudioTask = NULL; + gAudioTasks[0].task.t.data_size = 0; + gAudioTasks[1].task.t.data_size = 0; + osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1); + osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs, + ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs)); + gCurrAudioFrameDmaCount = 0; + gSampleDmaNumListItems = 0; + + sound_init_main_pools(gAudioInitPoolSize); + + for (i = 0; i < NUMAIBUFFERS; i++) { + gAiBuffers[i] = soundAlloc(&gAudioInitPool, AIBUFFER_LEN); + + for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { + gAiBuffers[i][j] = 0; + } + } + + gAudioResetPresetIdToLoad = 0; + gAudioResetStatus = 1; + audio_shut_down_and_reset_step(); + + // Not sure about these prints + eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0); + eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0); + eu_stubbed_printf_0("Main Heap Initialize.\n"); + + // Load headers for sounds and sequences + gSeqFileHeader = (ALSeqFile *) buf; + data = gMusicData; + audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10); + gSequenceCount = gSeqFileHeader->seqCount; + size = gSequenceCount * sizeof(ALSeqData) + 4; + size = ALIGN16(size); + gSeqFileHeader = soundAlloc(&gAudioInitPool, size); + audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size); + alSeqFileNew(gSeqFileHeader, data); + + // Load header for CTL (instrument metadata) + gAlCtlHeader = (ALSeqFile *) buf; + data = gSoundDataADSR; + audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, 0x10); + size = gAlCtlHeader->seqCount * sizeof(ALSeqData) + 4; + size = ALIGN16(size); + gCtlEntries = soundAlloc(&gAudioInitPool, gAlCtlHeader->seqCount * sizeof(struct CtlEntry)); + gAlCtlHeader = soundAlloc(&gAudioInitPool, size); + audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, size); + alSeqFileNew(gAlCtlHeader, data); + + // Load header for TBL (raw sound data) + gAlTbl = (ALSeqFile *) buf; + audio_dma_copy_immediate((uintptr_t) data, gAlTbl, 0x10); + size = gAlTbl->seqCount * sizeof(ALSeqData) + 4; + size = ALIGN16(size); + gAlTbl = soundAlloc(&gAudioInitPool, size); + audio_dma_copy_immediate((uintptr_t) gSoundDataRaw, gAlTbl, size); + alSeqFileNew(gAlTbl, gSoundDataRaw); + + // Load bank sets for each sequence + gAlBankSets = soundAlloc(&gAudioInitPool, 0x100); + audio_dma_copy_immediate((uintptr_t) gBankSetsData, gAlBankSets, 0x100); + + init_sequence_players(); + gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; + // Should probably contain the sizes of the data banks, but those aren't + // easily accessible from here. + eu_stubbed_printf_0("---------- Init Completed. ------------\n"); + eu_stubbed_printf_1(" Syndrv :[%6d]\n", 0); // gSoundDataADSR + eu_stubbed_printf_1(" Seqdrv :[%6d]\n", 0); // gMusicData + eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw + eu_stubbed_printf_0("---------------------------------------\n"); +} diff --git a/src/audio/eu/load.h b/src/audio/eu/load.h new file mode 100644 index 00000000..b73cc66d --- /dev/null +++ b/src/audio/eu/load.h @@ -0,0 +1,58 @@ +#ifndef AUDIO_LOAD_H +#define AUDIO_LOAD_H + +#include + +#include "internal.h" + +#define AUDIO_FRAME_DMA_QUEUE_SIZE 0x40 + +#define PRELOAD_BANKS 2 +#define PRELOAD_SEQUENCE 1 + +#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t)(ptr) != (uintptr_t)&gSequenceChannelNone) + +extern struct Note *gNotes; + +// Music in SM64 is played using 3 players: +// gSequencePlayers[0] is level background music +// gSequencePlayers[1] is misc music, like the puzzle jingle +// gSequencePlayers[2] is sound +extern struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; + +extern struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +extern struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; + +extern struct SequenceChannel gSequenceChannelNone; + +extern struct AudioListItem gLayerFreeList; +extern struct NotePool gNoteFreeLists; + +extern OSMesgQueue gCurrAudioFrameDmaQueue; +extern u32 gSampleDmaNumListItems; +extern ALSeqFile *gAlCtlHeader; +extern ALSeqFile *gAlTbl; +extern ALSeqFile *gSeqFileHeader; +extern u8 *gAlBankSets; + +extern struct CtlEntry *gCtlEntries; +extern struct AudioBufferParametersEU gAudioBufferParameters; +extern s32 gAiFrequency; +extern s32 gMaxAudioCmds; + +extern s32 gMaxSimultaneousNotes; +extern s32 gSamplesPerFrameTarget; +extern s32 gMinAiBufferLength; +extern s16 gTempoInternalToExternal; +extern s8 gAudioUpdatesPerFrame; // = 4 +extern s8 gSoundMode; + +void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg); +void decrease_sample_dma_ttls(void); +void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef); +void init_sample_dma_buffers(s32 arg0); +void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums); +void preload_sequence(u32 seqId, u8 preloadMask); +void load_sequence(u32 player, u32 seqId, s32 loadAsync); + +#endif // AUDIO_LOAD_H diff --git a/src/audio/eu/playback.c b/src/audio/eu/playback.c new file mode 100644 index 00000000..1386c215 --- /dev/null +++ b/src/audio/eu/playback.c @@ -0,0 +1,812 @@ +#include + +#include "heap.h" +#include "data.h" +#include "load.h" +#include "seqplayer.h" +#include "playback.h" +#include "synthesis.h" +#include "effects.h" +#include "../external.h" + +void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput); + +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol) +{ + struct NoteSubEu *sub = ¬e->noteSubEu; + f32 volRight, volLeft; + u8 strongRight; + u8 strongLeft; + s32 smallPanIndex; + u16 unkMask = ~0x80; + + pan &= unkMask; + + if (note->noteSubEu.stereoHeadsetEffects && gSoundMode == SOUND_MODE_HEADSET) { + smallPanIndex = pan >> 3; + if (smallPanIndex >= ARRAY_COUNT(gHeadsetPanQuantization)) { + smallPanIndex = ARRAY_COUNT(gHeadsetPanQuantization) - 1; + } + + sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; + sub->headsetPanRight = gHeadsetPanQuantization[ARRAY_COUNT(gHeadsetPanQuantization) - 1 - smallPanIndex]; + sub->stereoStrongRight = FALSE; + sub->stereoStrongLeft = FALSE; + sub->usesHeadsetPanEffects = TRUE; + + volLeft = gHeadsetPanVolume[pan]; + volRight = gHeadsetPanVolume[127 - pan]; + } else if (sub->stereoHeadsetEffects && gSoundMode == SOUND_MODE_STEREO) { + strongLeft = FALSE; + strongRight = FALSE; + sub->headsetPanLeft = 0; + sub->headsetPanRight = 0; + + sub->usesHeadsetPanEffects = FALSE; + + volLeft = gStereoPanVolume[pan]; + volRight = gStereoPanVolume[127 - pan]; + if (pan < 0x20) { + strongLeft = TRUE; + } else if (pan > 0x60) { + strongRight = TRUE; + } + + sub->stereoStrongRight = strongRight; + sub->stereoStrongLeft = strongLeft; + + } else if (gSoundMode == SOUND_MODE_MONO) { + volLeft = 0.707f; + volRight = 0.707f; + } else { + volLeft = gDefaultPanVolume[pan]; + volRight = gDefaultPanVolume[127 - pan]; + } + + if (velocity < 0.0f) { + stubbed_printf("Audio: setvol: volume minus %f\n", velocity); + velocity = 0.0f; + } + if (velocity > 32767.f) { + stubbed_printf("Audio: setvol: volume overflow %f\n", velocity); + velocity = 32767.f; + } + + sub->targetVolLeft = ((s32) (velocity * volLeft) & 0xffff) >> 5; + sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5; + + //! @bug for the change to UQ0.7, the if statement should also have been changed accordingly + if (sub->reverbVol != reverbVol) { + sub->reverbVol = reverbVol; + sub->envMixerNeedsInit = TRUE; + return; + } + + if (sub->needsInit) { + sub->envMixerNeedsInit = TRUE; + } else { + sub->envMixerNeedsInit = FALSE; + } +} + +#define MIN_RESAMPLING_RATE 1.99996f + +void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) { + f32 resamplingRate = 0.0f; + struct NoteSubEu *tempSub = ¬e->noteSubEu; + + if (resamplingRateInput < 0.0f) { + stubbed_printf("Audio: setpitch: pitch minus %f\n", resamplingRateInput); + resamplingRateInput = 0.0f; + } + if (resamplingRateInput < 2.0f) { + tempSub->hasTwoAdpcmParts = 0; + + if (MIN_RESAMPLING_RATE < resamplingRateInput) { + resamplingRate = MIN_RESAMPLING_RATE; + } else { + resamplingRate = resamplingRateInput; + } + + } else { + tempSub->hasTwoAdpcmParts = 1; + if (2 * MIN_RESAMPLING_RATE < resamplingRateInput) { + resamplingRate = MIN_RESAMPLING_RATE; + } else { + resamplingRate = resamplingRateInput * 0.5f; + } + } + note->noteSubEu.resamplingRateFixedPoint = (s32) (resamplingRate * 32768.0f); +} + +struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone) { + struct AudioBankSound *sound; + if (semitone < instrument->normalRangeLo) { + sound = &instrument->lowNotesSound; + } else if (semitone <= instrument->normalRangeHi) { + sound = &instrument->normalNotesSound; + } else { + sound = &instrument->highNotesSound; + } + return sound; +} + +struct Instrument *get_instrument_inner(s32 bankId, s32 instId) { + struct Instrument *inst; + + if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { + stubbed_printf("Audio: voiceman: No bank error %d\n", bankId); + gAudioErrorFlags = bankId + 0x10000000; + return NULL; + } + + if (instId >= gCtlEntries[bankId].numInstruments) { + stubbed_printf("Audio: voiceman: progNo. overflow %d,%d\n", + instId, gCtlEntries[bankId].numInstruments); + gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000; + return NULL; + } + + inst = gCtlEntries[bankId].instruments[instId]; + if (inst == NULL) { + stubbed_printf("Audio: voiceman: progNo. undefined %d,%d\n", bankId, instId); + gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000; + return inst; + } + + if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start + + gBankLoadedPool.persistent.pool.size)) + || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start + + gBankLoadedPool.temporary.pool.size))) { + return inst; + } + + stubbed_printf("Audio: voiceman: BAD Voicepointer %x,%d,%d\n", inst, bankId, instId); + gAudioErrorFlags = ((bankId << 8) + instId) + 0x2000000; + return NULL; +} + +struct Drum *get_drum(s32 bankId, s32 drumId) { + struct Drum *drum; + + if (drumId >= gCtlEntries[bankId].numDrums) { + stubbed_printf("Audio: voiceman: Percussion Overflow %d,%d\n", + drumId, gCtlEntries[bankId].numDrums); + gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000; + return NULL; + } + +#ifndef NO_SEGMENTED_MEMORY + if ((uintptr_t) gCtlEntries[bankId].drums < 0x80000000U) { + stubbed_printf("Percussion Pointer Error\n"); + return NULL; + } +#endif + + drum = gCtlEntries[bankId].drums[drumId]; + if (drum == NULL) { + stubbed_printf("Audio: voiceman: Percpointer NULL %d,%d\n", bankId, drumId); + gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000; + } + return drum; +} + +void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); + +void note_init(struct Note *note) { + if (note->parentLayer->adsr.releaseRate == 0) { + adsr_init(¬e->adsr, note->parentLayer->seqChannel->adsr.envelope, ¬e->adsrVolScale); + } else { + adsr_init(¬e->adsr, note->parentLayer->adsr.envelope, ¬e->adsrVolScale); + } + note->adsr.state = ADSR_STATE_INITIAL; + note->noteSubEu = gDefaultNoteSub; +} + +#define note_disable2 note_disable +void note_disable(struct Note *note) { + if (note->noteSubEu.needsInit == TRUE) { + note->noteSubEu.needsInit = FALSE; + } + else { + note_set_vel_pan_reverb(note, 0, 0x40, 0); + } + note->priority = NOTE_PRIORITY_DISABLED; + note->parentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; + note->noteSubEu.enabled = FALSE; + note->noteSubEu.finished = FALSE; +} + +void process_notes(void) { + f32 scale; + f32 frequency; + f32 velocity; + struct Note *note; + struct NotePlaybackState *playbackState; + struct NoteSubEu *noteSubEu; + UNUSED u8 pad[12]; + u8 reverbVol; + UNUSED u8 pad3; + u8 pan; + u8 bookOffset; + struct NoteAttributes *attributes; + s32 i; + + // Macro versions of audio_list_push_front and audio_list_remove. + // Should ideally be changed to use copt. +#define PREPEND(item, head_arg) \ + ((it = (item), it->prev != NULL) \ + ? it \ + : (it->prev = (head_arg), it->next = (head_arg)->next, (head_arg)->next->prev = it, \ + (head_arg)->next = it, (head_arg)->u.count++, it->pool = (head_arg)->pool, it)) +#define POP(item) \ + ((it = (item), it->prev == NULL) \ + ? it \ + : (it->prev->next = it->next, it->next->prev = it->prev, it->prev = NULL, it)) + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + playbackState = (struct NotePlaybackState *) ¬e->priority; + if (note->parentLayer != NO_LAYER) { +#ifndef NO_SEGMENTED_MEMORY + if ((uintptr_t) playbackState->parentLayer < 0x7fffffffU) { + continue; + } +#endif + if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) { + goto c; + } else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) { + eu_stubbed_printf_0("CAUTION:SUB IS SEPARATED FROM GROUP"); + sequence_channel_disable(playbackState->parentLayer->seqChannel); + playbackState->priority = NOTE_PRIORITY_STOPPING; + continue; + } else if (playbackState->parentLayer->seqChannel->seqPlayer->muted) { + if ((playbackState->parentLayer->seqChannel->muteBehavior + & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES))) { + goto c; + } + } + goto d; + if (1) { + c: + seq_channel_layer_note_release(playbackState->parentLayer); + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); + playbackState->priority = NOTE_PRIORITY_STOPPING; + } + } else if (playbackState->priority >= NOTE_PRIORITY_MIN) { + continue; + } + d: + if (playbackState->priority != NOTE_PRIORITY_DISABLED) { + noteSubEu = ¬e->noteSubEu; + if (playbackState->priority == NOTE_PRIORITY_STOPPING || noteSubEu->finished) { + if (playbackState->adsr.state == ADSR_STATE_DISABLED || noteSubEu->finished) { + if (playbackState->wantedParentLayer != NO_LAYER) { + note_disable(note); + if (playbackState->wantedParentLayer->seqChannel != NULL) { + note_init_for_layer(note, playbackState->wantedParentLayer); + note_vibrato_init(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->active, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + // don't skip + } else { + eu_stubbed_printf_0("Error:Wait Track disappear\n"); + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + goto skip; + } + } else { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + goto skip; + } + } + if (1) { + } + } else if (playbackState->adsr.state == ADSR_STATE_DISABLED) { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + goto skip; + } + + scale = adsr_update(&playbackState->adsr); + note_vibrato_update(note); + attributes = &playbackState->attributes; + if (playbackState->priority == NOTE_PRIORITY_STOPPING) { + frequency = attributes->freqScale; + velocity = attributes->velocity; + pan = attributes->pan; + reverbVol = attributes->reverbVol; + if (1) { + } + bookOffset = noteSubEu->bookOffset; + } else { + frequency = playbackState->parentLayer->noteFreqScale; + velocity = playbackState->parentLayer->noteVelocity; + pan = playbackState->parentLayer->notePan; + reverbVol = playbackState->parentLayer->seqChannel->reverbVol; + bookOffset = playbackState->parentLayer->seqChannel->bookOffset & 0x7; + } + + frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; + frequency *= gAudioBufferParameters.resampleRate; + velocity = velocity * scale * scale; + note_set_resampling_rate(note, frequency); + note_set_vel_pan_reverb(note, velocity, pan, reverbVol); + noteSubEu->bookOffset = bookOffset; + skip:; + } + } +#undef PREPEND +#undef POP +} + +void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLayer, s32 target) { + struct Note *note; + struct NoteAttributes *attributes; + + if (seqLayer == NO_LAYER) { + return; + } + + if (seqLayer->note == NULL) { + return; + } + + note = seqLayer->note; + attributes = ¬e->attributes; + + if (note->wantedParentLayer == seqLayer) { + note->wantedParentLayer = NO_LAYER; + } + + if (note->parentLayer != seqLayer) { + + if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER && + note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) { + // Just guessing that this printf goes here... it's hard to parse. + eu_stubbed_printf_0("Slow Release Batting\n"); + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; + } + return; + } + + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + if (note->adsr.state != ADSR_STATE_DECAY) { + attributes->freqScale = seqLayer->noteFreqScale; + attributes->velocity = seqLayer->noteVelocity; + attributes->pan = seqLayer->notePan; + if (seqLayer->seqChannel != NULL) { + attributes->reverbVol = seqLayer->seqChannel->reverbVol; + } + note->priority = NOTE_PRIORITY_STOPPING; + note->prevParentLayer = note->parentLayer; + note->parentLayer = NO_LAYER; + if (target == ADSR_STATE_RELEASE) { + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; + } else { + note->adsr.action |= ADSR_ACTION_DECAY; + if (seqLayer->adsr.releaseRate == 0) { + note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; + } else { + note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; + } + note->adsr.sustain = (FLOAT_CAST(seqLayer->seqChannel->adsr.sustain) * note->adsr.current) / 256.0f; + } + } + + if (target == ADSR_STATE_DECAY) { + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); + } +} + +void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_DECAY); +} + +void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_RELEASE); +} + +s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer, s32 waveId) { + f32 freqScale; + f32 ratio; + u8 sampleCountIndex; + + if (waveId < 128) { + stubbed_printf("Audio:Wavemem: Bad voiceno (%d)\n", waveId); + waveId = 128; + } + + freqScale = seqLayer->freqScale; + if (seqLayer->portamento.mode != 0 && 0.0f < seqLayer->portamento.extent) { + freqScale *= (seqLayer->portamento.extent + 1.0f); + } + if (freqScale < 1.0f) { + sampleCountIndex = 0; + ratio = 1.0465f; + } else if (freqScale < 2.0f) { + sampleCountIndex = 1; + ratio = 0.52325f; + } else if (freqScale < 4.0f) { + sampleCountIndex = 2; + ratio = 0.26263f; + } else { + sampleCountIndex = 3; + ratio = 0.13081f; + } + seqLayer->freqScale *= ratio; + note->waveId = waveId; + note->sampleCountIndex = sampleCountIndex; + + note->noteSubEu.sound.samples = &gWaveSamples[waveId - 128][sampleCountIndex * 64]; + + return sampleCountIndex; +} + +void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { + s32 sampleCountIndex; + s32 waveSampleCountIndex; + s32 waveId = seqLayer->instOrWave; + if (waveId == 0xff) { + waveId = seqLayer->seqChannel->instOrWave; + } + sampleCountIndex = note->sampleCountIndex; + waveSampleCountIndex = build_synthetic_wave(note, seqLayer, waveId); + note->synthesisState.samplePosInt = note->synthesisState.samplePosInt * euUnknownData_8030194c[waveSampleCountIndex] / euUnknownData_8030194c[sampleCountIndex]; +} + +void init_note_list(struct AudioListItem *list) { + list->prev = list; + list->next = list; + list->u.count = 0; +} + +void init_note_lists(struct NotePool *pool) { + init_note_list(&pool->disabled); + init_note_list(&pool->decaying); + init_note_list(&pool->releasing); + init_note_list(&pool->active); + pool->disabled.pool = pool; + pool->decaying.pool = pool; + pool->releasing.pool = pool; + pool->active.pool = pool; +} + +void init_note_free_list(void) { + s32 i; + + init_note_lists(&gNoteFreeLists); + for (i = 0; i < gMaxSimultaneousNotes; i++) { + gNotes[i].listItem.u.value = &gNotes[i]; + gNotes[i].listItem.prev = NULL; + audio_list_push_back(&gNoteFreeLists.disabled, &gNotes[i].listItem); + } +} + +void note_pool_clear(struct NotePool *pool) { + s32 i; + struct AudioListItem *source; + struct AudioListItem *cur; + struct AudioListItem *dest; + + for (i = 0; i < 4; i++) { + switch (i) { + case 0: + source = &pool->disabled; + dest = &gNoteFreeLists.disabled; + break; + + case 1: + source = &pool->decaying; + dest = &gNoteFreeLists.decaying; + break; + + case 2: + source = &pool->releasing; + dest = &gNoteFreeLists.releasing; + break; + + case 3: + source = &pool->active; + dest = &gNoteFreeLists.active; + break; + } + + for (;;) { + cur = source->next; + if (cur == source) { + break; + } + if (cur == NULL) { + eu_stubbed_printf_0("Audio: C-Alloc : Dealloc voice is NULL\n"); + break; + } + audio_list_remove(cur); + audio_list_push_back(dest, cur); + } + } +} + +void note_pool_fill(struct NotePool *pool, s32 count) { + s32 i; + s32 j; + struct Note *note; + struct AudioListItem *source; + struct AudioListItem *dest; + + note_pool_clear(pool); + + for (i = 0, j = 0; j < count; i++) { + if (i == 4) { + eu_stubbed_printf_1("Alloc Error:Dim voice-Alloc %d", count); + return; + } + + switch (i) { + case 0: + source = &gNoteFreeLists.disabled; + dest = &pool->disabled; + break; + + case 1: + source = &gNoteFreeLists.decaying; + dest = &pool->decaying; + break; + + case 2: + source = &gNoteFreeLists.releasing; + dest = &pool->releasing; + break; + + case 3: + source = &gNoteFreeLists.active; + dest = &pool->active; + break; + } + + while (j < count) { + note = audio_list_pop_back(source); + if (note == NULL) { + break; + } + audio_list_push_back(dest, ¬e->listItem); + j++; + } + } +} + +void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item) { + // add 'item' to the front of the list given by 'list', if it's not in any list + if (item->prev != NULL) { + eu_stubbed_printf_0("Error:Same List Add\n"); + } else { + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; + list->u.count++; + item->pool = list->pool; + } +} + +void audio_list_remove(struct AudioListItem *item) { + // remove 'item' from the list it's in, if any + if (item->prev == NULL) { + eu_stubbed_printf_0("Already Cut\n"); + } else { + item->prev->next = item->next; + item->next->prev = item->prev; + item->prev = NULL; + } +} + +struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) { + struct AudioListItem *cur = list->next; + struct AudioListItem *best; + + if (cur == list) { + return NULL; + } + + for (best = cur; cur != list; cur = cur->next) { + if (((struct Note *) best->u.value)->priority >= ((struct Note *) cur->u.value)->priority) { + best = cur; + } + } + + if (best == NULL) { + return NULL; + } + + if (limit <= ((struct Note *) best->u.value)->priority) { + return NULL; + } + + audio_list_remove(best); + return best->u.value; +} + +void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { + UNUSED s32 pad[4]; + s16 instId; + struct NoteSubEu *sub = ¬e->noteSubEu; + + note->prevParentLayer = NO_LAYER; + note->parentLayer = seqLayer; + note->priority = seqLayer->seqChannel->notePriority; + seqLayer->notePropertiesNeedInit = TRUE; + seqLayer->status = SOUND_LOAD_STATUS_DISCARDABLE; // "loaded" + seqLayer->note = note; + seqLayer->seqChannel->noteUnused = note; + seqLayer->seqChannel->layerUnused = seqLayer; + seqLayer->noteVelocity = 0.0f; + note_init(note); + instId = seqLayer->instOrWave; + if (instId == 0xff) { + instId = seqLayer->seqChannel->instOrWave; + } + sub->sound.audioBankSound = seqLayer->sound; + + if (instId >= 0x80) { + sub->isSyntheticWave = TRUE; + } else { + sub->isSyntheticWave = FALSE; + } + + if (sub->isSyntheticWave) { + build_synthetic_wave(note, seqLayer, instId); + } + sub->bankId = seqLayer->seqChannel->bankId; + sub->stereoHeadsetEffects = seqLayer->seqChannel->stereoHeadsetEffects; + sub->reverbIndex = seqLayer->seqChannel->reverbIndex & 3; +} + +void func_80319728(struct Note *note, struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_note_release(note->parentLayer); + note->wantedParentLayer = seqLayer; +} + +void note_release_and_take_ownership(struct Note *note, struct SequenceChannelLayer *seqLayer) { + note->wantedParentLayer = seqLayer; + note->priority = NOTE_PRIORITY_STOPPING; + + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; +} + +struct Note *alloc_note_from_disabled(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *note = audio_list_pop_back(&pool->disabled); + if (note != NULL) { + note_init_for_layer(note, seqLayer); + audio_list_push_front(&pool->active, ¬e->listItem); + } + return note; +} + +struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *note = audio_list_pop_back(&pool->decaying); + if (note != NULL) { + note_release_and_take_ownership(note, seqLayer); + audio_list_push_back(&pool->releasing, ¬e->listItem); + } + return note; +} + +struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *aNote; + + aNote = pop_node_with_lower_prio(&pool->active, seqLayer->seqChannel->notePriority); + + if (aNote == NULL) { + eu_stubbed_printf_0("Audio: C-Alloc : lowerPrio is NULL\n"); + } else { + func_80319728(aNote, seqLayer); + audio_list_push_back(&pool->releasing, &aNote->listItem); + } + + return aNote; +} + +struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { + struct Note *ret; + u32 policy = seqLayer->seqChannel->noteAllocPolicy; + + if (policy & NOTE_ALLOC_LAYER) { + ret = seqLayer->note; + if (ret != NULL && ret->prevParentLayer == seqLayer + && ret->wantedParentLayer == NO_LAYER + ) { + note_release_and_take_ownership(ret, seqLayer); + audio_list_remove(&ret->listItem); + audio_list_push_back(&ret->listItem.pool->releasing, &ret->listItem); + return ret; + } + } + + if (policy & NOTE_ALLOC_CHANNEL) { + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) { + eu_stubbed_printf_0("Sub Limited Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; + } + + if (policy & NOTE_ALLOC_SEQ) { + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; + } + + if (policy & NOTE_ALLOC_GLOBAL_FREELIST) { + if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; + } + + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; +} + +void note_init_all(void) { + struct Note *note; + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + note->noteSubEu = gZeroNoteSub; + note->priority = NOTE_PRIORITY_DISABLED; + note->parentLayer = NO_LAYER; + note->wantedParentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; + note->waveId = 0; + note->attributes.velocity = 0.0f; + note->adsrVolScale = 0; + note->adsr.state = ADSR_STATE_DISABLED; + note->adsr.action = 0; + note->vibratoState.active = FALSE; + note->portamento.cur = 0.0f; + note->portamento.speed = 0.0f; + note->synthesisState.synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); + } +} diff --git a/src/audio/playback.h b/src/audio/eu/playback.h similarity index 90% rename from src/audio/playback.h rename to src/audio/eu/playback.h index e2e15bf9..870b415f 100644 --- a/src/audio/playback.h +++ b/src/audio/eu/playback.h @@ -30,13 +30,8 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer); void reclaim_notes(void); void note_init_all(void); -#if defined(VERSION_SH) -void note_set_vel_pan_reverb(struct Note *note, struct ReverbInfo *reverbInfo); -#elif defined(VERSION_EU) void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol); -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone); struct Instrument *get_instrument_inner(s32 bankId, s32 instId); struct Drum *get_drum(s32 bankId, s32 drumId); @@ -44,7 +39,6 @@ void note_init_volume(struct Note *note); void note_set_frequency(struct Note *note, f32 frequency); void note_enable(struct Note *note); void note_disable(struct Note *note); -#endif #endif // AUDIO_PLAYBACK_H diff --git a/src/audio/port_eu.c b/src/audio/eu/port.c similarity index 91% rename from src/audio/port_eu.c rename to src/audio/eu/port.c index 5ec259c9..ca5156b7 100644 --- a/src/audio/port_eu.c +++ b/src/audio/eu/port.c @@ -1,12 +1,11 @@ #include #include "internal.h" +#include "port.h" #include "load.h" #include "data.h" #include "seqplayer.h" #include "synthesis.h" -#ifdef VERSION_EU - #ifdef __sgi #define stubbed_printf #else @@ -16,15 +15,10 @@ #define SAMPLES_TO_OVERPRODUCE 0x10 #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40 -#ifdef VERSION_JP -typedef u16 FadeT; -#else typedef s32 FadeT; -#endif extern volatile u8 gAudioResetStatus; extern u8 gAudioResetPresetIdToLoad; -extern OSMesgQueue *OSMesgQueues[]; extern struct EuAudioCmd sAudioCmd[0x100]; void func_8031D690(s32 player, FadeT fadeInTime); @@ -50,7 +44,7 @@ struct SPTask *create_next_audio_frame_task(void) { return NULL; } - osSendMesg(OSMesgQueues[0], (OSMesg) gAudioFrameCount, 0); + osSendMesg(OSMesgQueue0, (OSMesg) gAudioFrameCount, 0); gAudioTaskIndex ^= 1; gCurrAiBufferIndex++; @@ -69,7 +63,7 @@ struct SPTask *create_next_audio_frame_task(void) { gCurrAudioFrameDmaCount = 0; decrease_sample_dma_ttls(); - if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) { + if (osRecvMesg(OSMesgQueue2, &sp30, 0) != -1) { gAudioResetPresetIdToLoad = (u8) (s32) sp30; gAudioResetStatus = 5; } @@ -77,7 +71,7 @@ struct SPTask *create_next_audio_frame_task(void) { if (gAudioResetStatus != 0) { if (audio_shut_down_and_reset_step() == 0) { if (gAudioResetStatus == 0) { - osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueue3, (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK); } return NULL; } @@ -97,7 +91,7 @@ struct SPTask *create_next_audio_frame_task(void) { gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength; } - if (osRecvMesg(OSMesgQueues[1], &sp2C, OS_MESG_NOBLOCK) != -1) { + if (osRecvMesg(OSMesgQueue1, &sp2C, OS_MESG_NOBLOCK) != -1) { func_802ad7ec((u32) sp2C); } @@ -177,13 +171,8 @@ void eu_process_audio_cmd(struct EuAudioCmd *cmd) { const char undefportcmd[] = "Undefined Port Command %d\n"; -extern OSMesgQueue *OSMesgQueues[]; extern u8 D_EU_80302010; extern u8 D_EU_80302014; -extern OSMesg OSMesg0; -extern OSMesg OSMesg1; -extern OSMesg OSMesg2; -extern OSMesg OSMesg3; void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime) { if (fadeOutTime == 0) { @@ -192,7 +181,6 @@ void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime) { gSequencePlayers[player].fadeVelocity = -(gSequencePlayers[player].fadeVolume / fadeOutTime); gSequencePlayers[player].state = 2; gSequencePlayers[player].fadeRemainingFrames = fadeOutTime; - } void func_8031D690(s32 player, FadeT fadeInTime) { @@ -208,10 +196,10 @@ void func_8031D690(s32 player, FadeT fadeInTime) { void port_eu_init_queues(void) { D_EU_80302010 = 0; D_EU_80302014 = 0; - osCreateMesgQueue(OSMesgQueues[0], &OSMesg0, 1); - osCreateMesgQueue(OSMesgQueues[1], &OSMesg1, 4); - osCreateMesgQueue(OSMesgQueues[2], &OSMesg2, 1); - osCreateMesgQueue(OSMesgQueues[3], &OSMesg3, 1); + osCreateMesgQueue(OSMesgQueue0, OSMesg0, 1); + osCreateMesgQueue(OSMesgQueue1, OSMesg1, 4); + osCreateMesgQueue(OSMesgQueue2, OSMesg2, 1); + osCreateMesgQueue(OSMesgQueue3, OSMesg3, 1); } void func_802ad6f0(s32 arg0, s32 *arg1) { @@ -221,21 +209,21 @@ void func_802ad6f0(s32 arg0, s32 *arg1) { D_EU_80302010++; } -void func_802ad728(u32 arg0, f32 arg1) { +void port_cmd_f32(u32 arg0, f32 arg1) { func_802ad6f0(arg0, (s32*) &arg1); } -void func_802ad74c(u32 arg0, u32 arg1) { +void port_cmd_u32(u32 arg0, u32 arg1) { func_802ad6f0(arg0, (s32*) &arg1); } -void func_802ad770(u32 arg0, s8 arg1) { +void port_cmd_s8(u32 arg0, s8 arg1) { s32 sp1C = arg1 << 24; func_802ad6f0(arg0, &sp1C); } void func_802ad7a0(void) { - osSendMesg(OSMesgQueues[1], + osSendMesg(OSMesgQueue1, (OSMesg)(u32)((D_EU_80302014 & 0xff) << 8 | (D_EU_80302010 & 0xff)), OS_MESG_NOBLOCK); D_EU_80302014 = D_EU_80302010; @@ -320,4 +308,3 @@ void port_eu_init(void) { port_eu_init_queues(); } -#endif diff --git a/src/audio/eu/port.h b/src/audio/eu/port.h new file mode 100644 index 00000000..e9b51d51 --- /dev/null +++ b/src/audio/eu/port.h @@ -0,0 +1,29 @@ +#ifndef AUDIO_PORT_H +#define AUDIO_PORT_H + +#include + +extern OSMesg OSMesg0[1]; +extern OSMesgQueue OSMesgQueue0Data; +extern OSMesgQueue *OSMesgQueue0; + +extern OSMesg OSMesg1[4]; +extern OSMesgQueue OSMesgQueue1Data; +extern OSMesgQueue *OSMesgQueue1; + +extern OSMesg OSMesg2[1]; +extern OSMesgQueue OSMesgQueue2Data; +extern OSMesgQueue *OSMesgQueue2; + +extern OSMesg OSMesg3[1]; +extern OSMesgQueue OSMesgQueue3Data; +extern OSMesgQueue *OSMesgQueue3; + +// main thread -> sound thread dispatchers +void port_cmd_f32(u32 arg0, f32 arg1); +void port_cmd_u32(u32 arg0, u32 arg1); +void port_cmd_s8(u32 arg0, s8 arg1); + +void func_802ad7a0(void); + +#endif // AUDIO_PORT_H diff --git a/src/audio/eu/seqplayer.c b/src/audio/eu/seqplayer.c new file mode 100644 index 00000000..962ddccb --- /dev/null +++ b/src/audio/eu/seqplayer.c @@ -0,0 +1,1640 @@ +#include + +#include "data.h" +#include "effects.h" +#include "heap.h" +#include "load.h" +#include "seqplayer.h" + +#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) +#define PORTAMENTO_MODE(x) ((x).mode & ~0x80) +#define PORTAMENTO_MODE_1 1 +#define PORTAMENTO_MODE_2 2 +#define PORTAMENTO_MODE_3 3 +#define PORTAMENTO_MODE_4 4 +#define PORTAMENTO_MODE_5 5 + +void seq_channel_layer_process_script(struct SequenceChannelLayer *layer); +void sequence_channel_process_script(struct SequenceChannel *seqChannel); +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, + struct AdsrSettings *adsr); + +void sequence_channel_init(struct SequenceChannel *seqChannel) { + s32 i; + + seqChannel->enabled = FALSE; + seqChannel->finished = FALSE; + seqChannel->stopScript = FALSE; + seqChannel->stopSomething2 = FALSE; + seqChannel->hasInstrument = FALSE; + seqChannel->stereoHeadsetEffects = FALSE; + seqChannel->transposition = 0; + seqChannel->largeNotes = FALSE; + seqChannel->bookOffset = 0; + seqChannel->changes.as_u8 = 0xff; + seqChannel->scriptState.depth = 0; + seqChannel->newPan = 0x40; + seqChannel->panChannelWeight = 0x80; + seqChannel->noteUnused = NULL; + seqChannel->reverbIndex = 0; + seqChannel->reverbVol = 0; + seqChannel->notePriority = NOTE_PRIORITY_DEFAULT; + seqChannel->delay = 0; + seqChannel->adsr.envelope = gDefaultEnvelope; + seqChannel->adsr.releaseRate = 0x20; + seqChannel->adsr.sustain = 0; + seqChannel->vibratoRateTarget = 0x800; + seqChannel->vibratoRateStart = 0x800; + seqChannel->vibratoExtentTarget = 0; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoRateChangeDelay = 0; + seqChannel->vibratoExtentChangeDelay = 0; + seqChannel->vibratoDelay = 0; + seqChannel->volume = 1.0f; + seqChannel->volumeScale = 1.0f; + seqChannel->freqScale = 1.0f; + + for (i = 0; i < 8; i++) { + seqChannel->soundScriptIO[i] = -1; + } + + seqChannel->unused = FALSE; + init_note_lists(&seqChannel->notePool); +} + +s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { + struct SequenceChannelLayer *layer; + + if (seqChannel->layers[layerIndex] == NULL) { + struct SequenceChannelLayer *layer; + layer = audio_list_pop_back(&gLayerFreeList); + seqChannel->layers[layerIndex] = layer; + if (layer == NULL) { + seqChannel->layers[layerIndex] = NULL; + return -1; + } + } else { + seq_channel_layer_note_decay(seqChannel->layers[layerIndex]); + } + + layer = seqChannel->layers[layerIndex]; + layer->seqChannel = seqChannel; + layer->adsr = seqChannel->adsr; + layer->adsr.releaseRate = 0; + layer->enabled = TRUE; + layer->stopSomething = FALSE; + layer->continuousNotes = FALSE; + layer->finished = FALSE; + layer->ignoreDrumPan = FALSE; + layer->portamento.mode = 0; + layer->scriptState.depth = 0; + layer->status = SOUND_LOAD_STATUS_NOT_LOADED; + layer->noteDuration = 0x80; + layer->pan = 0x40; + layer->transposition = 0; + layer->delay = 0; + layer->duration = 0; + layer->delayUnused = 0; + layer->note = NULL; + layer->instrument = NULL; + layer->freqScale = 1.0f; + layer->velocitySquare = 0.0f; + layer->instOrWave = 0xff; + return 0; +} + +void seq_channel_layer_disable(struct SequenceChannelLayer *layer) { + if (layer != NULL) { + seq_channel_layer_note_decay(layer); + layer->enabled = FALSE; + layer->finished = TRUE; + } +} + +void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex) { + struct SequenceChannelLayer *layer = seqChannel->layers[layerIndex]; + + if (layer != NULL) { + audio_list_push_back(&gLayerFreeList, &layer->listItem); + seq_channel_layer_disable(layer); + seqChannel->layers[layerIndex] = NULL; + } +} + +void sequence_channel_disable(struct SequenceChannel *seqChannel) { + s32 i; + for (i = 0; i < LAYERS_MAX; i++) { + seq_channel_layer_free(seqChannel, i); + } + + note_pool_clear(&seqChannel->notePool); + seqChannel->enabled = FALSE; + seqChannel->finished = TRUE; +} + +struct SequenceChannel *allocate_sequence_channel(void) { + s32 i; + for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { + if (gSequenceChannels[i].seqPlayer == NULL) { + return &gSequenceChannels[i]; + } + } + return &gSequenceChannelNone; +} + +void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channelBits) { + struct SequenceChannel *seqChannel; + s32 i; + + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE && seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; + } + seqChannel = allocate_sequence_channel(); + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + eu_stubbed_printf_0("Audio:Track:Warning: No Free Notetrack\n"); + gAudioErrorFlags = i + 0x10000; + seqPlayer->channels[i] = seqChannel; + } else { + sequence_channel_init(seqChannel); + seqPlayer->channels[i] = seqChannel; + seqChannel->seqPlayer = seqPlayer; + seqChannel->bankId = seqPlayer->defaultBank[0]; + seqChannel->muteBehavior = seqPlayer->muteBehavior; + seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy; + } + } + channelBits = channelBits >> 1; + } +} + +void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 channelBits) { + struct SequenceChannel *seqChannel; + s32 i; + + eu_stubbed_printf_0("SUBTRACK DIM\n"); + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE) { + if (seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; + } + else { + stubbed_printf("Audio:Track: Warning SUBTRACK PARENT CHANGED\n"); + } + seqPlayer->channels[i] = &gSequenceChannelNone; + } + } + channelBits = channelBits >> 1; + } +} + +void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script) { + struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; + s32 i; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + struct SequencePlayer *bgMusic = &gSequencePlayers[0]; + struct SequencePlayer *miscMusic = &gSequencePlayers[1]; + + if (seqPlayer == bgMusic) { + stubbed_printf("GROUP 0:"); + } else if (seqPlayer == miscMusic) { + stubbed_printf("GROUP 1:"); + } else { + stubbed_printf("SEQID %d,BANKID %d\n", + seqPlayer->seqId, seqPlayer->defaultBank[0]); + } + stubbed_printf("ERR:SUBTRACK %d NOT ALLOCATED\n", channelIndex); + } else { + seqChannel->enabled = TRUE; + seqChannel->finished = FALSE; + seqChannel->scriptState.depth = 0; + seqChannel->scriptState.pc = script; + seqChannel->delay = 0; + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != NULL) { + seq_channel_layer_free(seqChannel, i); + } + } + } +} + +void sequence_player_disable(struct SequencePlayer *seqPlayer) { + sequence_player_disable_channels(seqPlayer, 0xffff); + note_pool_clear(&seqPlayer->notePool); + seqPlayer->finished = TRUE; + seqPlayer->enabled = FALSE; + + if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) + ) { + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_DISCARDABLE; + } + + if (IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) + ) { + gBankLoadStatus[seqPlayer->defaultBank[0]] = SOUND_LOAD_STATUS_DISCARDABLE; + } + + // (Note that if this is called from alloc_bank_or_seq, the side will get swapped + // later in that function. Thus, we signal that we want to load into the slot + // of the bank that we no longer need.) + if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[0].id) { + gBankLoadedPool.temporary.nextSide = 1; + } else if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[1].id) { + gBankLoadedPool.temporary.nextSide = 0; + } +} + +/** + * Add an item to the end of a list, if it's not already in any list. + */ +void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item) { + if (item->prev != NULL) { + eu_stubbed_printf_0("Error:Same List Add\n"); + } else { + list->prev->next = item; + item->prev = list->prev; + item->next = list; + list->prev = item; + list->u.count++; + item->pool = list->pool; + } +} + +/** + * Remove the last item from a list, and return it (or NULL if empty). + */ +void *audio_list_pop_back(struct AudioListItem *list) { + struct AudioListItem *item = list->prev; + if (item == list) { + return NULL; + } + item->prev->next = list; + list->prev = item->prev; + item->prev = NULL; + list->u.count--; + return item->u.value; +} + +void init_layer_freelist(void) { + s32 i; + + gLayerFreeList.prev = &gLayerFreeList; + gLayerFreeList.next = &gLayerFreeList; + gLayerFreeList.u.count = 0; + gLayerFreeList.pool = NULL; + + for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { + gSequenceLayers[i].listItem.u.value = &gSequenceLayers[i]; + gSequenceLayers[i].listItem.prev = NULL; + audio_list_push_back(&gLayerFreeList, &gSequenceLayers[i].listItem); + } +} + +u8 m64_read_u8(struct M64ScriptState *state) { + return *(state->pc++); +} + +s16 m64_read_s16(struct M64ScriptState *state) { + s16 ret = *(state->pc++) << 8; + ret = *(state->pc++) | ret; + return ret; +} + +u16 m64_read_compressed_u16(struct M64ScriptState *state) { + u16 ret = *(state->pc++); + if (ret & 0x80) { + ret = (ret << 8) & 0x7f00; + ret = *(state->pc++) | ret; + } + return ret; +} + +void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { + struct SequencePlayer *seqPlayer; + struct SequenceChannel *seqChannel; + UNUSED u32 pad0; + struct M64ScriptState *state; + struct Portamento *portamento; + struct AudioBankSound *sound; + struct Instrument *instrument; + struct Drum *drum; + s32 temp_a0_5; + u16 sp3A; + s32 sameSound; + UNUSED u32 pad1; + u8 cmd; + UNUSED u8 cmdSemitone; + f32 tuning; + s32 vel; + UNUSED s32 usedSemitone; + f32 freqScale; + f32 temp_f12; + f32 temp_f2; + + sameSound = TRUE; + if (layer->enabled == FALSE) { + return; + } + + if (layer->delay > 1) { + layer->delay--; + if (!layer->stopSomething && layer->delay <= layer->duration) { + seq_channel_layer_note_decay(layer); + layer->stopSomething = TRUE; + } + return; + } + + if (!layer->continuousNotes) { + seq_channel_layer_note_decay(layer); + } + + if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 || + PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) { + layer->portamento.mode = 0; + } + + seqChannel = layer->seqChannel; + seqPlayer = seqChannel->seqPlayer; + layer->notePropertiesNeedInit = TRUE; + + for (;;) { + state = &layer->scriptState; + cmd = m64_read_u8(state); + + if (cmd <= 0xc0) { + break; + } + + switch (cmd) { + case 0xff: // layer_end; function return or end of script + if (state->depth == 0) { + // N.B. this function call is *not* inlined even though it's + // within the same file, unlike in the rest of this function. + seq_channel_layer_disable(layer); + return; + } + state->pc = state->stack[--state->depth]; + break; + + case 0xfc: // layer_call + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Macro Level Over Error!\n"); + } + sp3A = m64_read_s16(state); + state->stack[state->depth++] = state->pc; + state->pc = seqPlayer->seqData + sp3A; + break; + + case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Macro Level Over Error!\n"); + } + state->remLoopIters[state->depth] = m64_read_u8(state); + state->stack[state->depth++] = state->pc; + break; + + case 0xf7: // layer_loopend + if (--state->remLoopIters[state->depth - 1] != 0) { + state->pc = state->stack[state->depth - 1]; + } else { + state->depth--; + } + break; + + case 0xfb: // layer_jump + sp3A = m64_read_s16(state); + state->pc = seqPlayer->seqData + sp3A; + break; + + case 0xf4: + state->pc += (s8)m64_read_u8(state); + break; + + case 0xc1: // layer_setshortnotevelocity + case 0xca: // layer_setpan + temp_a0_5 = *(state->pc++); + if (cmd == 0xc1) { + layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5); + } else { + layer->pan = temp_a0_5; + } + break; + + case 0xc2: // layer_transpose; set transposition in semitones + case 0xc9: // layer_setshortnoteduration + temp_a0_5 = *(state->pc++); + if (cmd == 0xc9) { + layer->noteDuration = temp_a0_5; + } else { + layer->transposition = temp_a0_5; + } + break; + + case 0xc4: // layer_somethingon + case 0xc5: // layer_somethingoff + if (cmd == 0xc4) { + layer->continuousNotes = TRUE; + } else { + layer->continuousNotes = FALSE; + } + seq_channel_layer_note_decay(layer); + break; + + case 0xc3: // layer_setshortnotedefaultplaypercentage + sp3A = m64_read_compressed_u16(state); + layer->shortNoteDefaultPlayPercentage = sp3A; + break; + + case 0xc6: // layer_setinstr + cmd = m64_read_u8(state); + if (cmd >= 0x7f) { + if (cmd == 0x7f) { + layer->instOrWave = 0; + } else { + layer->instOrWave = cmd; + layer->instrument = NULL; + } + + if (1) { + } + + if (cmd == 0xff) { + layer->adsr.releaseRate = 0; + } + break; + } + + if ((layer->instOrWave = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr)) == 0) { + eu_stubbed_printf_1("WARNING: NPRG: cannot change %d\n", cmd); + layer->instOrWave = 0xff; + } + break; + + case 0xc7: // layer_portamento + layer->portamento.mode = m64_read_u8(state); + + // cmd is reused for the portamento's semitone + cmd = m64_read_u8(state) + seqChannel->transposition + + layer->transposition + seqPlayer->transposition; + + if (cmd >= 0x80) { + cmd = 0; + } + + layer->portamentoTargetNote = cmd; + + // If special, the next param is u8 instead of var + if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { + layer->portamentoTime = *((state)->pc++); + break; + } + + sp3A = m64_read_compressed_u16(state); + layer->portamentoTime = sp3A; + break; + + case 0xc8: // layer_disableportamento + layer->portamento.mode = 0; + break; + + case 0xcb: + sp3A = m64_read_s16(state); + layer->adsr.envelope = (struct AdsrEnvelope *) (seqPlayer->seqData + sp3A); + layer->adsr.releaseRate = m64_read_u8(state); + break; + + case 0xcc: + layer->ignoreDrumPan = TRUE; + break; + + default: + switch (cmd & 0xf0) { + case 0xd0: // layer_setshortnotevelocityfromtable + sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xf]; + layer->velocitySquare = (f32)(sp3A * sp3A); + break; + case 0xe0: // layer_setshortnotedurationfromtable + layer->noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf]; + break; + default: + eu_stubbed_printf_1("Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n", cmd); + break; + } + } + } + + if (cmd == 0xc0) { // layer_delay + layer->delay = m64_read_compressed_u16(state); + layer->stopSomething = TRUE; + } else { + layer->stopSomething = FALSE; + + if (seqChannel->largeNotes == TRUE) { + switch (cmd & 0xc0) { + case 0x00: // layer_note0 (play percentage, velocity, duration) + sp3A = m64_read_compressed_u16(state); + vel = *(state->pc++); + layer->noteDuration = *(state->pc++); + layer->playPercentage = sp3A; + break; + + case 0x40: // layer_note1 (play percentage, velocity) + sp3A = m64_read_compressed_u16(state); + vel = *(state->pc++); + layer->noteDuration = 0; + layer->playPercentage = sp3A; + break; + + case 0x80: // layer_note2 (velocity, duration; uses last play percentage) + sp3A = layer->playPercentage; + vel = *(state->pc++); + layer->noteDuration = *(state->pc++); + break; + } + + // the remaining bits are used for the semitone + cmd -= (cmd & 0xc0); + layer->velocitySquare = (f32)(vel) * (f32)vel; + } else { + switch (cmd & 0xc0) { + case 0x00: // play note, type 0 (play percentage) + sp3A = m64_read_compressed_u16(state); + layer->playPercentage = sp3A; + break; + + case 0x40: // play note, type 1 (uses default play percentage) + sp3A = layer->shortNoteDefaultPlayPercentage; + break; + + case 0x80: // play note, type 2 (uses last play percentage) + sp3A = layer->playPercentage; + break; + } + + // the remaining bits are used for the semitone + cmd -= cmd & 0xc0; + } + + layer->delay = sp3A; + layer->duration = layer->noteDuration * sp3A >> 8; + if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0) + || seqChannel->stopSomething2 + ) { + layer->stopSomething = TRUE; + } else { + s32 temp = layer->instOrWave; + if (temp == 0xff) { + temp = seqChannel->instOrWave; + } + if (temp == 0) + { // drum + // cmd is reused for the drum semitone + cmd += seqChannel->transposition + layer->transposition; + + drum = get_drum(seqChannel->bankId, cmd); + if (drum == NULL) { + layer->stopSomething = TRUE; + } else { + layer->adsr.envelope = drum->envelope; + layer->adsr.releaseRate = drum->releaseRate; + if (!layer->ignoreDrumPan) { + layer->pan = drum->pan; + } + layer->sound = &drum->sound; + layer->freqScale = layer->sound->tuning; + } + } else { // instrument + // cmd is reused for the instrument semitone + cmd += seqPlayer->transposition + seqChannel->transposition + layer->transposition; + + if (cmd >= 0x80) { + layer->stopSomething = TRUE; + } else { + if (layer->instOrWave == 0xffu) { + instrument = seqChannel->instrument; + } else { + instrument = layer->instrument; + } + + if (layer->portamento.mode != 0) { + if (layer->portamentoTargetNote < cmd) { + vel = cmd; + } else { + vel = layer->portamentoTargetNote; + } + + if (instrument != NULL) { + sound = instrument_get_audio_bank_sound(instrument, vel); + sameSound = (sound == layer->sound); + layer->sound = sound; + tuning = sound->tuning; + } else { + layer->sound = NULL; + tuning = 1.0f; + } + + temp_f2 = gNoteFrequencies[cmd] * tuning; + temp_f12 = gNoteFrequencies[layer->portamentoTargetNote] * tuning; + + portamento = &layer->portamento; + switch (PORTAMENTO_MODE(layer->portamento)) { + case PORTAMENTO_MODE_1: + case PORTAMENTO_MODE_3: + case PORTAMENTO_MODE_5: + freqScale = temp_f12; + break; + + case PORTAMENTO_MODE_2: + case PORTAMENTO_MODE_4: + default: + freqScale = temp_f2; + break; + } + + portamento->extent = temp_f2 / freqScale - 1.0f; + + if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { + portamento->speed = 32512.0f * FLOAT_CAST(seqPlayer->tempo) + / ((f32) layer->delay * (f32) gTempoInternalToExternal + * FLOAT_CAST(layer->portamentoTime)); + } else { + portamento->speed = 127.0f / FLOAT_CAST(layer->portamentoTime); + } + portamento->cur = 0.0f; + layer->freqScale = freqScale; + if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_5) { + layer->portamentoTargetNote = cmd; + } + } else if (instrument != NULL) { + sound = instrument_get_audio_bank_sound(instrument, cmd); + sameSound = (sound == layer->sound); + layer->sound = sound; + layer->freqScale = gNoteFrequencies[cmd] * sound->tuning; + } else { + layer->sound = NULL; + layer->freqScale = gNoteFrequencies[cmd]; + } + } + } + layer->delayUnused = layer->delay; + } + } + + if (layer->stopSomething == TRUE) { + if (layer->note != NULL || layer->continuousNotes) { + seq_channel_layer_note_decay(layer); + } + return; + } + + cmd = FALSE; + if (!layer->continuousNotes) { + cmd = TRUE; + } else if (layer->note == NULL || layer->status == SOUND_LOAD_STATUS_NOT_LOADED) { + cmd = TRUE; + } else if (sameSound == FALSE) { + seq_channel_layer_note_decay(layer); + cmd = TRUE; + } + else if (layer != layer->note->parentLayer) { + cmd = TRUE; + } + else if (layer->sound == NULL) { + init_synthetic_wave(layer->note, layer); + } + + if (cmd != FALSE) { + layer->note = alloc_note(layer); + } + + if (layer->note != NULL && layer->note->parentLayer == layer) { + note_vibrato_init(layer->note); + } + if (seqChannel) { + } +} + +u8 audioString106[] = "Audio: Note:Velocity Error %d\n"; +u8 audioString107[] = "Error: Your assignchannel is stolen.\n"; + +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) { + struct Instrument *inst; + inst = get_instrument_inner(seqChannel->bankId, instId); + if (inst == NULL) { + *instOut = NULL; + return 0; + } + adsr->envelope = inst->envelope; + adsr->releaseRate = inst->releaseRate; + *instOut = inst; + instId++; + return instId; +} + +void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { + if (instId >= 0x80) { + seqChannel->instOrWave = instId; + seqChannel->instrument = NULL; + } else if (instId == 0x7f) { + seqChannel->instOrWave = 0; + seqChannel->instrument = (struct Instrument *) 1; + } else { + if ((seqChannel->instOrWave = + get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr)) == 0) + { + seqChannel->hasInstrument = FALSE; + return; + } + } + seqChannel->hasInstrument = TRUE; +} + +void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume) { + seqChannel->volume = FLOAT_CAST(volume) / 127.0f; +} + +void sequence_channel_process_script(struct SequenceChannel *seqChannel) { + struct M64ScriptState *state; + struct SequencePlayer *seqPlayer; + u8 cmd; + s8 temp; + u8 loBits; + u16 sp5A; + s32 sp38; + s8 value; + s32 i; + u8 *seqData; + + if (!seqChannel->enabled) { + return; + } + + if (seqChannel->stopScript) { + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != NULL) { + seq_channel_layer_process_script(seqChannel->layers[i]); + } + } + return; + } + + seqPlayer = seqChannel->seqPlayer; + if (seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT) != 0) { + return; + } + + if (seqChannel->delay != 0) { + seqChannel->delay--; + } + + state = &seqChannel->scriptState; + if (seqChannel->delay == 0) { + for (;;) { + cmd = m64_read_u8(state); + + if (cmd > 0xc0) + { + switch (cmd) { + case 0xff: // chan_end + if (state->depth == 0) { + sequence_channel_disable(seqChannel); + goto out; + } else { + state->pc = state->stack[--state->depth]; + } + break; + + case 0xfe: // chan_delay1 + goto out; + + case 0xfd: // chan_delay + seqChannel->delay = m64_read_compressed_u16(state); + goto out; + + case 0xea: + seqChannel->stopScript = TRUE; + goto out; + case 0xfc: // chan_call + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Audio:Track :Call Macro Level Over Error!\n"); + } + sp5A = m64_read_s16(state); + state->stack[state->depth++] = state->pc; + state->pc = seqPlayer->seqData + sp5A; + break; + + case 0xf8: // chan_loop; loop start, N iterations (or 256 if N = 0) + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Audio:Track :Loops Macro Level Over Error!\n"); + } + state->remLoopIters[state->depth] = m64_read_u8(state); + state->stack[state->depth++] = state->pc; + break; + + case 0xf7: // chan_loopend + state->remLoopIters[state->depth - 1]--; + if (state->remLoopIters[state->depth - 1] != 0) { + state->pc = state->stack[state->depth - 1]; + } else { + state->depth--; + } + break; + + case 0xf6: // chan_break; break loop, if combined with jump + state->depth--; + break; + + case 0xfb: // chan_jump + case 0xfa: // chan_beqz + case 0xf9: // chan_bltz + case 0xf5: // chan_bgez + sp5A = m64_read_s16(state); + if (cmd == 0xfa && value != 0) { + break; + } + if (cmd == 0xf9 && value >= 0) { + break; + } + if (cmd == 0xf5 && value < 0) { + break; + } + state->pc = seqPlayer->seqData + sp5A; + break; + + case 0xf4: // chan_jump_rel + case 0xf3: // chan_beqz_rel + case 0xf2: // chan_bltz_rel + temp = m64_read_u8(state); + if (cmd == 0xf3 && value != 0) { + break; + } + if (cmd == 0xf2 && value >= 0) { + break; + } + state->pc += temp; + break; + + case 0xf1: // chan_reservenotes + note_pool_clear(&seqChannel->notePool); + note_pool_fill(&seqChannel->notePool, m64_read_u8(state)); + break; + + case 0xf0: // chan_unreservenotes + note_pool_clear(&seqChannel->notePool); + break; + + case 0xc2: // chan_setdyntable + sp5A = m64_read_s16(state); + seqChannel->dynTable = (void *) (seqPlayer->seqData + sp5A); + break; + + case 0xc5: // chan_dynsetdyntable + if (value != -1) { + seqData = (*seqChannel->dynTable)[value]; + sp38 = (u16)((seqData[0] << 8) + seqData[1]); + seqChannel->dynTable = (void *) (seqPlayer->seqData + sp38); + } + break; + + case 0xeb: // chan_setbankandinstr + cmd = m64_read_u8(state); + // Switch to the cmd's (0-indexed) bank in this sequence's + // bank set. Note that in the binary format (not in the JSON!) + // the banks are listed backwards, so we counts from the back. + // (gAlBankSets[offset] is number of banks) + sp38 = ((u16 *) gAlBankSets)[seqPlayer->seqId]; + loBits = *(sp38 + gAlBankSets); + cmd = gAlBankSets[(s32)sp38 + loBits - cmd]; + + if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL) + { + seqChannel->bankId = cmd; + } else { + eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", cmd); + } + // fallthrough + + case 0xc1: // chan_setinstr ("set program"?) + set_instrument(seqChannel, m64_read_u8(state)); + break; + + case 0xc3: // chan_largenotesoff + seqChannel->largeNotes = FALSE; + break; + + case 0xc4: // chan_largenoteson + seqChannel->largeNotes = TRUE; + break; + + case 0xdf: // chan_setvol + sequence_channel_set_volume(seqChannel, m64_read_u8(state)); + seqChannel->changes.as_bitfields.volume = TRUE; + break; + + case 0xe0: // chan_setvolscale + seqChannel->volumeScale = FLOAT_CAST(m64_read_u8(state)) / 128.0f; + seqChannel->changes.as_bitfields.volume = TRUE; + break; + + case 0xde: // chan_freqscale; pitch bend using raw frequency multiplier N/2^15 (N is u16) + sp5A = m64_read_s16(state); + seqChannel->freqScale = FLOAT_CAST(sp5A) / 32768.0f; + seqChannel->changes.as_bitfields.freqScale = TRUE; + break; + + case 0xd3: // chan_pitchbend; pitch bend by <= 1 octave in either direction (-127..127) + // (m64_read_u8(state) is really s8 here) + cmd = m64_read_u8(state) + 127; + seqChannel->freqScale = gPitchBendFrequencyScale[cmd]; + seqChannel->changes.as_bitfields.freqScale = TRUE; + break; + + case 0xdd: // chan_setpan + seqChannel->newPan = m64_read_u8(state); + seqChannel->changes.as_bitfields.pan = TRUE; + break; + + case 0xdc: // chan_setpanmix; set proportion of pan to come from channel (0..128) + seqChannel->panChannelWeight = m64_read_u8(state); + seqChannel->changes.as_bitfields.pan = TRUE; + break; + + case 0xdb: // chan_transpose; set transposition in semitones + temp = *state->pc++; + seqChannel->transposition = temp; + break; + + case 0xda: // chan_setenvelope + sp5A = m64_read_s16(state); + seqChannel->adsr.envelope = (struct AdsrEnvelope *) (seqPlayer->seqData + sp5A); + break; + + case 0xd9: // chan_setdecayrelease + seqChannel->adsr.releaseRate = m64_read_u8(state); + break; + + case 0xd8: // chan_setvibratoextent + seqChannel->vibratoExtentTarget = m64_read_u8(state) * 8; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoExtentChangeDelay = 0; + break; + + case 0xd7: // chan_setvibratorate + seqChannel->vibratoRateStart = seqChannel->vibratoRateTarget = + m64_read_u8(state) * 32; + seqChannel->vibratoRateChangeDelay = 0; + break; + + case 0xe2: // chan_setvibratoextentlinear + seqChannel->vibratoExtentStart = m64_read_u8(state) * 8; + seqChannel->vibratoExtentTarget = m64_read_u8(state) * 8; + seqChannel->vibratoExtentChangeDelay = m64_read_u8(state) * 16; + break; + + case 0xe1: // chan_setvibratoratelinear + seqChannel->vibratoRateStart = m64_read_u8(state) * 32; + seqChannel->vibratoRateTarget = m64_read_u8(state) * 32; + seqChannel->vibratoRateChangeDelay = m64_read_u8(state) * 16; + break; + + case 0xe3: // chan_setvibratodelay + seqChannel->vibratoDelay = m64_read_u8(state) * 16; + break; + + case 0xd4: // chan_setreverb + seqChannel->reverbVol = m64_read_u8(state); + break; + + case 0xc6: // chan_setbank; switch bank within set + cmd = m64_read_u8(state); + // Switch to the temp's (0-indexed) bank in this sequence's + // bank set. Note that in the binary format (not in the JSON!) + // the banks are listed backwards, so we counts from the back. + // (gAlBankSets[offset] is number of banks) + sp38 = ((u16 *) gAlBankSets)[seqPlayer->seqId]; + loBits = *(sp38 + gAlBankSets); + cmd = gAlBankSets[(s32)sp38 + loBits - cmd]; + if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL) + { + seqChannel->bankId = cmd; + } else { + eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", cmd); + } + break; + + case 0xc7: // chan_writeseq; write to sequence data (!) + { + cmd = m64_read_u8(state); + sp5A = m64_read_s16(state); + seqData = seqPlayer->seqData + sp5A; + *seqData = (u8)value + cmd; + } + break; + + case 0xc8: // chan_subtract + case 0xc9: // chan_bitand + case 0xcc: // chan_setval + temp = m64_read_u8(state); + if (cmd == 0xc8) { + value -= temp; + } else if (cmd == 0xcc) { + value = temp; + } else { + value &= temp; + } + break; + + case 0xca: // chan_setmutebhv + seqChannel->muteBehavior = m64_read_u8(state); + break; + + case 0xcb: // chan_readseq + sp38 = (u16)m64_read_s16(state) + value; + value = seqPlayer->seqData[sp38]; + break; + + case 0xd0: // chan_stereoheadseteffects + seqChannel->stereoHeadsetEffects = m64_read_u8(state); + break; + + case 0xd1: // chan_setnoteallocationpolicy + seqChannel->noteAllocPolicy = m64_read_u8(state); + break; + + case 0xd2: // chan_setsustain + seqChannel->adsr.sustain = m64_read_u8(state); + break; + case 0xe5: + seqChannel->reverbIndex = m64_read_u8(state); + break; + case 0xe4: // chan_dyncall + if (value != -1) { + if (state->depth >= 4) { + eu_stubbed_printf_0("Audio:Track: CTBLCALL Macro Level Over Error!\n"); + } + seqData = (*seqChannel->dynTable)[value]; + state->stack[state->depth++] = state->pc; + sp38 = (u16)((seqData[0] << 8) + seqData[1]); + state->pc = seqPlayer->seqData + sp38; + + if (0 && sp38 >= gSeqFileHeader->seqArray[seqPlayer->seqId].len) { + eu_stubbed_printf_3("Err :Sub %x ,address %x:Undefined SubTrack Function %x", seqChannel, state->pc, sp38); + } + } + break; + + case 0xe6: + seqChannel->bookOffset = m64_read_u8(state); + break; + + case 0xe7: + sp5A = m64_read_s16(state); + seqData = seqPlayer->seqData + sp5A; + seqChannel->muteBehavior = *seqData++; + seqChannel->noteAllocPolicy = *seqData++; + seqChannel->notePriority = *seqData++; + seqChannel->transposition = (s8) *seqData++; + seqChannel->newPan = *seqData++; + seqChannel->panChannelWeight = *seqData++; + seqChannel->reverbVol = *seqData++; + seqChannel->reverbIndex = *seqData++; + seqChannel->changes.as_bitfields.pan = TRUE; + break; + + case 0xe8: + seqChannel->muteBehavior = m64_read_u8(state); + seqChannel->noteAllocPolicy = m64_read_u8(state); + seqChannel->notePriority = m64_read_u8(state); + seqChannel->transposition = (s8) m64_read_u8(state); + seqChannel->newPan = m64_read_u8(state); + seqChannel->panChannelWeight = m64_read_u8(state); + seqChannel->reverbVol = m64_read_u8(state); + seqChannel->reverbIndex = m64_read_u8(state); + seqChannel->changes.as_bitfields.pan = TRUE; + break; + + case 0xec: + seqChannel->vibratoExtentTarget = 0; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoExtentChangeDelay = 0; + seqChannel->vibratoRateTarget = 0; + seqChannel->vibratoRateStart = 0; + seqChannel->vibratoRateChangeDelay = 0; + seqChannel->freqScale = 1.0f; + break; + + case 0xe9: // chan_setnotepriority + seqChannel->notePriority = m64_read_u8(state); + break; + } + } else { + loBits = cmd & 0xf; + + switch (cmd & 0xf0) { + case 0x00: // chan_testlayerfinished + if (seqChannel->layers[loBits] != NULL) { + value = seqChannel->layers[loBits]->finished; + } + else { + value = -1; + } + break; + + // sh: 0x70 + case 0x70: // chan_iowriteval; write data back to audio lib + seqChannel->soundScriptIO[loBits] = value; + break; + + case 0x80: // chan_ioreadval; read data from audio lib + value = seqChannel->soundScriptIO[loBits]; + if (loBits < 4) { + seqChannel->soundScriptIO[loBits] = -1; + } + break; + + // sh: 0x50 + case 0x50: // chan_ioreadvalsub; subtract with read data from audio lib + value -= seqChannel->soundScriptIO[loBits]; + break; + + // sh: 0x00 + case 0x60: // chan_delayshort + seqChannel->delay = loBits; + goto out; + + case 0x90: // chan_setlayer + sp5A = m64_read_s16(state); + if (seq_channel_set_layer(seqChannel, loBits) == 0) { + if (1) {} + seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; + } + break; + + case 0xa0: // chan_freelayer + seq_channel_layer_free(seqChannel, loBits); + break; + + case 0xb0: // chan_dynsetlayer + if (value != -1 && seq_channel_set_layer(seqChannel, loBits) != -1) { + seqData = (*seqChannel->dynTable)[value]; + sp5A = ((seqData[0] << 8) + seqData[1]); + seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; + } + break; + + case 0x10: // chan_startchannel + sp5A = m64_read_s16(state); + sequence_channel_enable(seqPlayer, loBits, seqPlayer->seqData + sp5A); + break; + + case 0x20: // chan_disablechannel + sequence_channel_disable(seqPlayer->channels[loBits]); + break; + + case 0x30: // chan_iowriteval2; write data back to audio lib for another channel + cmd = m64_read_u8(state); + seqPlayer->channels[loBits]->soundScriptIO[cmd] = value; + break; + + case 0x40: // chan_ioreadval2; read data from audio lib from another channel + cmd = m64_read_u8(state); + value = seqPlayer->channels[loBits]->soundScriptIO[cmd]; + break; + } + } + } + } + out: + + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != 0) { + seq_channel_layer_process_script(seqChannel->layers[i]); + } + } +} + +void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { + u8 cmd; + u8 loBits; + u8 temp; + s32 value; + s32 i; + u16 u16v; + u8 *seqData; + struct M64ScriptState *state; + s32 temp32; + + if (seqPlayer->enabled == FALSE) { + return; + } + + if (seqPlayer->bankDmaInProgress == TRUE) { + if (osRecvMesg(&seqPlayer->bankDmaMesgQueue, NULL, 0) == -1) { + return; + } + if (seqPlayer->bankDmaRemaining == 0) { + seqPlayer->bankDmaInProgress = FALSE; + patch_audio_bank( + (struct AudioBank *) (gCtlEntries[seqPlayer->loadingBankId].instruments - 1), + gAlTbl->seqArray[seqPlayer->loadingBankId].offset, + gCtlEntries[seqPlayer->loadingBankId].numInstruments, + gCtlEntries[seqPlayer->loadingBankId].numDrums); + gCtlEntries[seqPlayer->loadingBankId].drums = + ((struct AudioBank *) (gCtlEntries[seqPlayer->loadingBankId].instruments - 1))->drums; + gBankLoadStatus[seqPlayer->loadingBankId] = SOUND_LOAD_STATUS_COMPLETE; + } else { + audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, + &seqPlayer->bankDmaRemaining, &seqPlayer->bankDmaMesgQueue, + &seqPlayer->bankDmaIoMesg); + } + return; + } + + if (seqPlayer->seqDmaInProgress == TRUE) { + if (osRecvMesg(&seqPlayer->seqDmaMesgQueue, NULL, 0) == -1) { + return; + } +#ifndef AVOID_UB + if (temp) { + } +#endif + seqPlayer->seqDmaInProgress = FALSE; + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; + } + + // If discarded, bail out. + if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) == FALSE + || ( + IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) == FALSE)) { + eu_stubbed_printf_1("Disappear Sequence or Bank %d\n", seqPlayer->seqId); + sequence_player_disable(seqPlayer); + return; + } + + // Remove possible SOUND_LOAD_STATUS_DISCARDABLE marks. + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; + + gBankLoadStatus[seqPlayer->defaultBank[0]] = SOUND_LOAD_STATUS_COMPLETE; + + if (seqPlayer->muted && (seqPlayer->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT) != 0) { + return; + } + + // Check if we surpass the number of ticks needed for a tatum, else stop. + seqPlayer->tempoAcc += seqPlayer->tempo; + if (seqPlayer->tempoAcc < gTempoInternalToExternal) { + return; + } + seqPlayer->tempoAcc -= (u16) gTempoInternalToExternal; + + state = &seqPlayer->scriptState; + if (seqPlayer->delay > 1) { +#ifndef AVOID_UB + if (temp) { + } +#endif + seqPlayer->delay--; + } else { + seqPlayer->recalculateVolume = 1; + for (;;) { + cmd = m64_read_u8(state); + if (cmd == 0xff) { // seq_end + if (state->depth == 0) { + sequence_player_disable(seqPlayer); + break; + } + state->pc = state->stack[--state->depth]; + } + + if (cmd == 0xfd) { // seq_delay + seqPlayer->delay = m64_read_compressed_u16(state); + break; + } + + if (cmd == 0xfe) { // seq_delay1 + seqPlayer->delay = 1; + break; + } + + if (cmd >= 0xc0) { + switch (cmd) { + case 0xff: // seq_end + break; + + case 0xfc: // seq_call + u16v = m64_read_s16(state); + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Macro Level Over Error!\n"); + } + state->stack[state->depth++] = state->pc; + state->pc = seqPlayer->seqData + u16v; + break; + + case 0xf8: // seq_loop; loop start, N iterations (or 256 if N = 0) + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Macro Level Over Error!\n"); + } + state->remLoopIters[state->depth] = m64_read_u8(state); + state->stack[state->depth++] = state->pc; + break; + + case 0xf7: // seq_loopend + state->remLoopIters[state->depth - 1]--; + if (state->remLoopIters[state->depth - 1] != 0) { + state->pc = state->stack[state->depth - 1]; + } else { + state->depth--; + } + break; + + case 0xfb: // seq_jump + case 0xfa: // seq_beqz; jump if == 0 + case 0xf9: // seq_bltz; jump if < 0 + case 0xf5: // seq_bgez; jump if >= 0 + u16v = m64_read_s16(state); + if (cmd == 0xfa && value != 0) { + break; + } + if (cmd == 0xf9 && value >= 0) { + break; + } + if (cmd == 0xf5 && value < 0) { + break; + } + state->pc = seqPlayer->seqData + u16v; + break; + + case 0xf4: + case 0xf3: + case 0xf2: + temp = m64_read_u8(state); + if (cmd == 0xf3 && value != 0) { + break; + } + if (cmd == 0xf2 && value >= 0) { + break; + } + state->pc += (s8) temp; + break; + + case 0xf1: // seq_reservenotes + note_pool_clear(&seqPlayer->notePool); + note_pool_fill(&seqPlayer->notePool, m64_read_u8(state)); + break; + + case 0xf0: // seq_unreservenotes + note_pool_clear(&seqPlayer->notePool); + break; + + case 0xdf: // seq_transpose; set transposition in semitones + seqPlayer->transposition = 0; + // fallthrough + + case 0xde: // seq_transposerel; add transposition + seqPlayer->transposition += (s8) m64_read_u8(state); + break; + + case 0xdd: // seq_settempo (bpm) + case 0xdc: // seq_addtempo (bpm) + temp = m64_read_u8(state); + if (cmd == 0xdd) { + seqPlayer->tempo = temp * TEMPO_SCALE; + } else { + seqPlayer->tempo += (s8) temp * TEMPO_SCALE; + } + + if (seqPlayer->tempo > gTempoInternalToExternal) { + seqPlayer->tempo = gTempoInternalToExternal; + } + + //if (cmd) {} + + if ((s16) seqPlayer->tempo <= 0) { + seqPlayer->tempo = 1; + } + break; + + case 0xda: + cmd = m64_read_u8(state); + u16v = m64_read_s16(state); + switch (cmd) { + case SEQUENCE_PLAYER_STATE_0: + case SEQUENCE_PLAYER_STATE_FADE_OUT: + if (seqPlayer->state != SEQUENCE_PLAYER_STATE_2) { + seqPlayer->fadeTimerUnkEu = u16v; + seqPlayer->state = cmd; + } + break; + case SEQUENCE_PLAYER_STATE_2: + seqPlayer->fadeRemainingFrames = u16v; + seqPlayer->state = cmd; + seqPlayer->fadeVelocity = + (0.0f - seqPlayer->fadeVolume) / (s32)(u16v & 0xFFFFu); + break; + } + break; + + case 0xdb: + temp32 = m64_read_u8(state); + switch (seqPlayer->state) { + case SEQUENCE_PLAYER_STATE_2: + break; + case SEQUENCE_PLAYER_STATE_FADE_OUT: + seqPlayer->state = SEQUENCE_PLAYER_STATE_0; + seqPlayer->fadeVolume = 0.0f; + // fallthrough + case SEQUENCE_PLAYER_STATE_0: + seqPlayer->fadeRemainingFrames = seqPlayer->fadeTimerUnkEu; + if (seqPlayer->fadeTimerUnkEu != 0) { + seqPlayer->fadeVelocity = (temp32 / 127.0f - seqPlayer->fadeVolume) / FLOAT_CAST(seqPlayer->fadeRemainingFrames); + } else { + seqPlayer->fadeVolume = temp32 / 127.0f; + } + } + break; + + case 0xd9: + temp = m64_read_u8(state); + seqPlayer->fadeVolumeScale = (s8) temp / 127.0f; + break; + + case 0xd7: // seq_initchannels + u16v = m64_read_s16(state); + sequence_player_init_channels(seqPlayer, u16v); + break; + + case 0xd6: // seq_disablechannels + u16v = m64_read_s16(state); + sequence_player_disable_channels(seqPlayer, u16v); + break; + + case 0xd5: // seq_setmutescale + temp = m64_read_u8(state); + seqPlayer->muteVolumeScale = (f32)(s8) temp / 127.0f; + break; + + case 0xd4: // seq_mute + seqPlayer->muted = TRUE; + break; + + case 0xd3: // seq_setmutebhv + seqPlayer->muteBehavior = m64_read_u8(state); + break; + + case 0xd2: // seq_setshortnotevelocitytable + case 0xd1: // seq_setshortnotedurationtable + u16v = m64_read_s16(state); + seqData = seqPlayer->seqData + u16v; + if (cmd == 0xd2) { + seqPlayer->shortNoteVelocityTable = seqData; + } else { + seqPlayer->shortNoteDurationTable = seqData; + } + break; + + case 0xd0: // seq_setnoteallocationpolicy + seqPlayer->noteAllocPolicy = m64_read_u8(state); + break; + + case 0xcc: // seq_setval + value = m64_read_u8(state); + break; + + case 0xc9: // seq_bitand + value &= m64_read_u8(state); + break; + + case 0xc8: // seq_subtract + value = value - m64_read_u8(state); + break; + + default: + eu_stubbed_printf_1("Group:Undefine upper C0h command (%x)\n", cmd); + break; + } + } else { + loBits = cmd & 0xf; + switch (cmd & 0xf0) { + case 0x00: // seq_testchdisabled + value = seqPlayer->channels[loBits]->finished; + break; + case 0x10: + break; + case 0x20: + break; + case 0x40: + break; + case 0x50: // seq_subvariation + value -= seqPlayer->seqVariationEu[0]; + break; + case 0x60: + break; + case 0x70: // seq_setvariation + seqPlayer->seqVariationEu[0] = value; + break; + case 0x80: // seq_getvariation + value = seqPlayer->seqVariationEu[0]; + break; + case 0x90: // seq_startchannel + u16v = m64_read_s16(state); + sequence_channel_enable(seqPlayer, loBits, seqPlayer->seqData + u16v); + break; + case 0xa0: + break; + + default: + eu_stubbed_printf_0("Group:Undefined Command\n"); + break; + } + } + } + } + + for (i = 0; i < CHANNELS_MAX; i++) { + if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE) { + sequence_channel_process_script(seqPlayer->channels[i]); + } + } +} + +// This runs 240 times per second. +void process_sequences(UNUSED s32 iterationsRemaining) { + s32 i; + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + if (gSequencePlayers[i].enabled == TRUE) { + sequence_player_process_sequence(&gSequencePlayers[i]); + sequence_player_process_sound(&gSequencePlayers[i]); + } + } + process_notes(); +} + +void init_sequence_player(u32 player) { + struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; + sequence_player_disable(seqPlayer); + seqPlayer->muted = FALSE; + seqPlayer->delay = 0; + seqPlayer->state = 1; + seqPlayer->fadeRemainingFrames = 0; + seqPlayer->fadeTimerUnkEu = 0; + seqPlayer->tempoAcc = 0; + seqPlayer->tempo = 120 * TEMPO_SCALE; // 120 BPM + seqPlayer->transposition = 0; + seqPlayer->muteBehavior = MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_SOFTEN; + seqPlayer->noteAllocPolicy = 0; + seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; + seqPlayer->shortNoteDurationTable = gDefaultShortNoteDurationTable; + seqPlayer->fadeVolume = 1.0f; + seqPlayer->fadeVolumeScale = 1.0f; + seqPlayer->fadeVelocity = 0.0f; + seqPlayer->volume = 0.0f; + seqPlayer->muteVolumeScale = 0.5f; +} + +void init_sequence_players(void) { + // Initialization function, called from audio_init + s32 i, j; + + for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { + gSequenceChannels[i].seqPlayer = NULL; + gSequenceChannels[i].enabled = FALSE; + // @bug Size of wrong array. Zeroes out second half of gSequenceChannels[0], + // all of gSequenceChannels[1..31], and part of gSequenceLayers[0]. + // However, this is only called at startup, so it's harmless. +#ifdef AVOID_UB +#define LAYERS_SIZE LAYERS_MAX +#else +#define LAYERS_SIZE ARRAY_COUNT(gSequenceLayers) +#endif + for (j = 0; j < LAYERS_SIZE; j++) { + gSequenceChannels[i].layers[j] = NULL; + } + } + + init_layer_freelist(); + + for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { + gSequenceLayers[i].seqChannel = NULL; + gSequenceLayers[i].enabled = FALSE; + } + + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + for (j = 0; j < CHANNELS_MAX; j++) { + gSequencePlayers[i].channels[j] = &gSequenceChannelNone; + } + + gSequencePlayers[i].seqVariationEu[0] = -1; + gSequencePlayers[i].bankDmaInProgress = FALSE; + gSequencePlayers[i].seqDmaInProgress = FALSE; + init_note_lists(&gSequencePlayers[i].notePool); + init_sequence_player(i); + } +} + diff --git a/src/audio/seqplayer.h b/src/audio/eu/seqplayer.h similarity index 100% rename from src/audio/seqplayer.h rename to src/audio/eu/seqplayer.h diff --git a/src/audio/synthesis.c b/src/audio/eu/synthesis.c similarity index 59% rename from src/audio/synthesis.c rename to src/audio/eu/synthesis.c index 5bc8c784..1430756c 100644 --- a/src/audio/synthesis.c +++ b/src/audio/eu/synthesis.c @@ -1,4 +1,3 @@ -#if !defined(VERSION_SH) && !defined(VERSION_CN) #include #include "synthesis.h" @@ -7,7 +6,6 @@ #include "load.h" #include "seqplayer.h" #include "internal.h" -#include "external.h" #define DMEM_ADDR_TEMP 0x0 @@ -45,39 +43,20 @@ struct VolumeChange { }; u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); -#ifdef VERSION_EU u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s16 *aiBuf, s32 bufLen, u64 *cmd); u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad); u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags); u64 *process_envelope(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, u32 flags); u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight); -#else -u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd); -u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad); -u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags); -u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, - u32 flags); -u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, - s32 headsetPanSettings, struct VolumeChange *vol); -u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight); -#endif -#ifdef VERSION_EU struct SynthesisReverb gSynthesisReverbs[4]; u8 sAudioSynthesisPad[0x10]; -#else -struct SynthesisReverb gSynthesisReverb; -u8 sAudioSynthesisPad[0x20]; -#endif -#ifdef VERSION_EU s16 gVolume; s8 gUseReverb; s8 gNumSynthesisReverbs; struct NoteSubEu *gNoteSubsEu; -#endif -#ifdef VERSION_EU f32 gLeftVolRampings[3][1024]; f32 gRightVolRampings[3][1024]; f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above @@ -85,9 +64,7 @@ f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n"; u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n"; -#endif -#ifdef VERSION_EU // Equivalent functionality as the US/JP version, // just that the reverb structure is chosen from an array with index void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) { @@ -141,62 +118,7 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) item->numSamplesAfterDownsampling = nSamples; item->chunkLen = chunkLen; } -#else -void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { - struct ReverbRingBufferItem *item; - s32 srcPos; - s32 dstPos; - s32 nSamples; - s32 numSamplesAfterDownsampling; - s32 excessiveSamples; - if (gReverbDownsampleRate != 1) { - if (gSynthesisReverb.framesLeftToIgnore == 0) { - // Now that the RSP has finished, downsample the samples produced two frames ago by skipping - // samples. - item = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; - // Touches both left and right since they are adjacent in memory - osInvalDCache(item->toDownsampleLeft, DEFAULT_LEN_2CH); - - for (srcPos = 0, dstPos = 0; dstPos < item->lengthA / 2; - srcPos += gReverbDownsampleRate, dstPos++) { - gSynthesisReverb.ringBuffer.left[dstPos + item->startPos] = - item->toDownsampleLeft[srcPos]; - gSynthesisReverb.ringBuffer.right[dstPos + item->startPos] = - item->toDownsampleRight[srcPos]; - } - for (dstPos = 0; dstPos < item->lengthB / 2; srcPos += gReverbDownsampleRate, dstPos++) { - gSynthesisReverb.ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos]; - gSynthesisReverb.ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos]; - } - } - } - item = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; - - numSamplesAfterDownsampling = chunkLen / gReverbDownsampleRate; - if (((numSamplesAfterDownsampling + gSynthesisReverb.nextRingBufferPos) - gSynthesisReverb.bufSizePerChannel) < 0) { - // There is space in the ring buffer before it wraps around - item->lengthA = numSamplesAfterDownsampling * 2; - item->lengthB = 0; - item->startPos = (s32) gSynthesisReverb.nextRingBufferPos; - gSynthesisReverb.nextRingBufferPos += numSamplesAfterDownsampling; - } else { - // Ring buffer wrapped around - excessiveSamples = - (numSamplesAfterDownsampling + gSynthesisReverb.nextRingBufferPos) - gSynthesisReverb.bufSizePerChannel; - nSamples = numSamplesAfterDownsampling - excessiveSamples; - item->lengthA = nSamples * 2; - item->lengthB = excessiveSamples * 2; - item->startPos = gSynthesisReverb.nextRingBufferPos; - gSynthesisReverb.nextRingBufferPos = excessiveSamples; - } - // These fields are never read later - item->numSamplesAfterDownsampling = numSamplesAfterDownsampling; - item->chunkLen = chunkLen; -} -#endif - -#ifdef VERSION_EU u64 *synthesis_load_reverb_ring_buffer(u64 *cmd, u16 addr, u16 srcOffset, s32 len, s32 reverbIndex) { aSetBuffer(cmd++, 0, addr, 0, len); aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[srcOffset])); @@ -206,9 +128,7 @@ u64 *synthesis_load_reverb_ring_buffer(u64 *cmd, u16 addr, u16 srcOffset, s32 le return cmd; } -#endif -#ifdef VERSION_EU u64 *synthesis_save_reverb_ring_buffer(u64 *cmd, u16 addr, u16 destOffset, s32 len, s32 reverbIndex) { aSetBuffer(cmd++, 0, 0, addr, len); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[destOffset])); @@ -218,9 +138,7 @@ u64 *synthesis_save_reverb_ring_buffer(u64 *cmd, u16 addr, u16 destOffset, s32 l return cmd; } -#endif -#ifdef VERSION_EU void synthesis_load_note_subs_eu(s32 updateIndex) { struct NoteSubEu *src; struct NoteSubEu *dest; @@ -237,32 +155,7 @@ void synthesis_load_note_subs_eu(s32 updateIndex) { } } } -#endif -#ifndef VERSION_EU -s32 get_volume_ramping(u16 sourceVol, u16 targetVol, s32 arg2) { - // This roughly computes 2^16 * (targetVol / sourceVol) ^ (8 / arg2), - // but with discretizations of targetVol, sourceVol and arg2. - f32 ret; - switch (arg2) { - default: - ret = gVolRampingLhs136[targetVol >> 8] * gVolRampingRhs136[sourceVol >> 8]; - break; - case 128: - ret = gVolRampingLhs128[targetVol >> 8] * gVolRampingRhs128[sourceVol >> 8]; - break; - case 136: - ret = gVolRampingLhs136[targetVol >> 8] * gVolRampingRhs136[sourceVol >> 8]; - break; - case 144: - ret = gVolRampingLhs144[targetVol >> 8] * gVolRampingRhs144[sourceVol >> 8]; - break; - } - return ret; -} -#endif - -#ifdef VERSION_EU // TODO: (Scrub C) pointless mask and whitespace u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { s32 i, j; @@ -318,49 +211,8 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { *writtenCmds = cmd - cmdBuf; return cmd; } -#else -// bufLen will be divisible by 16 -u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { - s32 chunkLen; - s32 i; - u32 *aiBufPtr = (u32 *) aiBuf; - u64 *cmd = cmdBuf + 1; - s32 v0; - - aSegment(cmdBuf, 0, 0); - - for (i = gAudioUpdatesPerFrame; i > 0; i--) { - if (i == 1) { - // 'bufLen' will automatically be divisible by 8, no need to round - chunkLen = bufLen; - } else { - v0 = bufLen / i; - // chunkLen = v0 rounded to nearest multiple of 8 - chunkLen = v0 - (v0 & 7); - - if ((v0 & 7) >= 4) { - chunkLen += 8; - } - } - process_sequences(i - 1); - if (gSynthesisReverb.useReverb != 0) { - prepare_reverb_ring_buffer(chunkLen, gAudioUpdatesPerFrame - i); - } - cmd = synthesis_do_one_audio_update((s16 *) aiBufPtr, chunkLen, cmd, gAudioUpdatesPerFrame - i); - bufLen -= chunkLen; - aiBufPtr += chunkLen; - } - if (gSynthesisReverb.framesLeftToIgnore != 0) { - gSynthesisReverb.framesLeftToIgnore--; - } - gSynthesisReverb.curFrame ^= 1; - *writtenCmds = cmd - cmdBuf; - return cmd; -} -#endif -#ifdef VERSION_EU u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { struct ReverbRingBufferItem *item; s16 startPad; @@ -425,9 +277,7 @@ u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { } return cmd; } -#endif -#ifdef VERSION_EU u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { struct NoteSubEu *noteSubEu; u8 noteIndices[56]; @@ -501,203 +351,62 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); return cmd; } -#else -u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { - UNUSED s32 pad1[1]; - s16 ra; - s16 t4; - UNUSED s32 pad[2]; - struct ReverbRingBufferItem *v1; - UNUSED s32 pad2[1]; - s16 temp; - v1 = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; - - if (gSynthesisReverb.useReverb == 0) { - aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); - cmd = synthesis_process_notes(aiBuf, bufLen, cmd); - } else { - if (gReverbDownsampleRate == 1) { - // Put the oldest samples in the ring buffer into the wet channels - aSetLoadBufferPair(cmd++, 0, v1->startPos); - if (v1->lengthB != 0) { - // Ring buffer wrapped - aSetLoadBufferPair(cmd++, v1->lengthA, 0); - temp = 0; - } - - // Use the reverb sound as initial sound for this audio update - aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); - - // (Hopefully) lower the volume of the wet channels. New reverb will later be mixed into - // these channels. - aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); - // 0x8000 here is -100% - aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_WET_LEFT_CH, - /*out*/ DMEM_ADDR_WET_LEFT_CH); - } else { - // Same as above but upsample the previously downsampled samples used for reverb first - temp = 0; //! jesus christ - t4 = (v1->startPos & 7) * 2; - ra = ALIGN(v1->lengthA + t4, 4); - aSetLoadBufferPair(cmd++, 0, v1->startPos - t4 / 2); - if (v1->lengthB != 0) { - // Ring buffer wrapped - aSetLoadBufferPair(cmd++, ra, 0); - //! We need an empty statement (even an empty ';') here to make the function match (because IDO). - //! However, copt removes extraneous statements and dead code. So we need to trick copt - //! into thinking 'temp' could be undefined, and luckily the compiler optimizes out the - //! useless assignment. - ra = ra + temp; - } - aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, bufLen << 1); - aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateLeft)); - aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_RIGHT_CH, bufLen << 1); - aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateRight)); - aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); - aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_LEFT_CH, /*out*/ DMEM_ADDR_LEFT_CH); - aDMEMMove(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); - } - cmd = synthesis_process_notes(aiBuf, bufLen, cmd); - if (gReverbDownsampleRate == 1) { - aSetSaveBufferPair(cmd++, 0, v1->lengthA, v1->startPos); - if (v1->lengthB != 0) { - // Ring buffer wrapped - aSetSaveBufferPair(cmd++, v1->lengthA, v1->lengthB, 0); - } - } else { - // Downsampling is done later by CPU when RSP is done, therefore we need to have double - // buffering. Left and right buffers are adjacent in memory. - aSetBuffer(cmd++, 0, 0, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); - aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex].toDownsampleLeft)); - gSynthesisReverb.resampleFlags = 0; - } - } - return cmd; -} -#endif - -#ifdef VERSION_EU // Processes just one note, not all u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED s16 *aiBuf, s32 bufLen, u64 *cmd) { UNUSED s32 pad0[3]; -#else -u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { - s32 noteIndex; // sp174 - struct Note *note; // s7 - UNUSED u8 pad0[0x08]; -#endif - struct AudioBankSample *audioBookSample; // sp164, sp138 - struct AdpcmLoop *loopInfo; // sp160, sp134 - s16 *curLoadedBook = NULL; // sp154, sp130 -#ifdef VERSION_EU + struct AudioBankSample *audioBookSample; + struct AdpcmLoop *loopInfo; + s16 *curLoadedBook = NULL; UNUSED u8 padEU[0x04]; -#endif UNUSED u8 pad8[0x04]; -#ifndef VERSION_EU - u16 resamplingRateFixedPoint; // sp5c, sp11A -#endif - s32 noteFinished; // 150 t2, sp124 - s32 restart; // 14c t3, sp120 - s32 flags; // sp148, sp11C -#ifdef VERSION_EU - u16 resamplingRateFixedPoint; // sp5c, sp11A -#endif - UNUSED u8 pad7[0x0c]; // sp100 + s32 noteFinished; + s32 restart; + s32 flags; + u16 resamplingRateFixedPoint; + UNUSED u8 pad7[0x0c]; UNUSED s32 tempBufLen; -#ifdef VERSION_EU - s32 sp130; //sp128, sp104 + s32 sp130; UNUSED u32 pad9; -#else - UNUSED u32 pad9; - s32 sp130; //sp128, sp104 -#endif - s32 nAdpcmSamplesProcessed; // signed required for US + s32 nAdpcmSamplesProcessed; s32 t0; -#ifdef VERSION_EU - u8 *sampleAddr; // sp120, spF4 + u8 *sampleAddr; s32 s6; -#else - s32 s6; - u8 *sampleAddr; // sp120, spF4 -#endif -#ifdef VERSION_EU - s32 samplesLenAdjusted; // 108, spEC + s32 samplesLenAdjusted; // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange // behavior with the break near the end of the loop, causing US and JP to need a goto instead UNUSED s32 samplesLenInt; - s32 endPos; // sp110, spE4 - s32 nSamplesToProcess; // sp10c/a0, spE0 + s32 endPos; + s32 nSamplesToProcess; s32 s2; -#else - // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange - // behavior with the break near the end of the loop, causing US and JP to need a goto instead - UNUSED s32 samplesLenInt; - s32 samplesLenAdjusted; // 108 - s32 s2; - s32 endPos; // sp110, spE4 - s32 nSamplesToProcess; // sp10c/a0, spE0 -#endif s32 leftRight; s32 s3; - s32 s5; //s4 + s32 s5; - u32 samplesLenFixedPoint; // v1_1 - s32 nSamplesInThisIteration; // v1_2 + u32 samplesLenFixedPoint; + s32 nSamplesInThisIteration; u32 a3; -#ifndef VERSION_EU - s32 t9; -#endif u8 *v0_2; - s32 nParts; // spE8, spBC - s32 curPart; // spE4, spB8 + s32 nParts; + s32 curPart; -#ifndef VERSION_EU - f32 resamplingRate; // f12 -#endif s32 temp; -#ifdef VERSION_EU s32 s5Aligned; -#endif - s32 resampledTempLen; // spD8, spAC - u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA + s32 resampledTempLen; + u16 noteSamplesDmemAddrBeforeResampling; -#ifndef VERSION_EU - for (noteIndex = 0; noteIndex < gMaxSimultaneousNotes; noteIndex++) { - note = &gNotes[noteIndex]; -#ifdef VERSION_US - //! This function requires note->enabled to be volatile, but it breaks other functions like note_enable. - //! Casting to a struct with just the volatile bitfield works, but there may be a better way to match. - if (((struct vNote *)note)->enabled && IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { -#else - if (IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { -#endif - gAudioErrorFlags = (note->bankId << 8) + noteIndex + 0x1000000; - } else if (((struct vNote *)note)->enabled) { -#else if (note->noteSubEu.enabled == FALSE) { return cmd; } else { -#endif flags = 0; -#ifdef VERSION_EU tempBufLen = bufLen; -#endif -#ifdef VERSION_EU if (noteSubEu->needsInit == TRUE) { -#else - if (note->needsInit == TRUE) { -#endif flags = A_INIT; -#ifndef VERSION_EU - note->samplePosInt = 0; - note->samplePosFrac = 0; -#else synthesisState->restart = FALSE; synthesisState->samplePosInt = 0; synthesisState->samplePosFrac = 0; @@ -705,67 +414,30 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { synthesisState->curVolRight = 1; synthesisState->prevHeadsetPanRight = 0; synthesisState->prevHeadsetPanLeft = 0; -#endif } -#ifndef VERSION_EU - if (note->frequency < US_FLOAT(2.0)) { - nParts = 1; - if (note->frequency > US_FLOAT(1.99996)) { - note->frequency = US_FLOAT(1.99996); - } - resamplingRate = note->frequency; - } else { - // If frequency is > 2.0, the processing must be split into two parts - nParts = 2; - if (note->frequency >= US_FLOAT(3.99993)) { - note->frequency = US_FLOAT(3.99993); - } - resamplingRate = note->frequency * US_FLOAT(.5); - } - - resamplingRateFixedPoint = (u16)(s32)(resamplingRate * 32768.0f); - samplesLenFixedPoint = note->samplePosFrac + (resamplingRateFixedPoint * bufLen) * 2; - note->samplePosFrac = samplesLenFixedPoint & 0xFFFF; // 16-bit store, can't reuse -#else resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint; nParts = noteSubEu->hasTwoAdpcmParts + 1; samplesLenFixedPoint = (resamplingRateFixedPoint * tempBufLen * 2) + synthesisState->samplePosFrac; synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF; -#endif -#ifdef VERSION_EU if (noteSubEu->isSyntheticWave) { cmd = load_wave_samples(cmd, noteSubEu, synthesisState, samplesLenFixedPoint >> 0x10); noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE; synthesisState->samplePosInt += samplesLenFixedPoint >> 0x10; } -#else - if (note->sound == NULL) { - // A wave synthesis note (not ADPCM) - - cmd = load_wave_samples(cmd, note, samplesLenFixedPoint >> 0x10); - noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + note->samplePosInt * 2; - note->samplePosInt += (samplesLenFixedPoint >> 0x10); - flags = 0; - } -#endif else { // ADPCM note -#ifdef VERSION_EU audioBookSample = noteSubEu->sound.audioBankSound->sample; -#else - audioBookSample = note->sound->sample; -#endif loopInfo = audioBookSample->loop; endPos = loopInfo->end; sampleAddr = audioBookSample->sampleAddr; resampledTempLen = 0; for (curPart = 0; curPart < nParts; curPart++) { - nAdpcmSamplesProcessed = 0; // s8 - s5 = 0; // s4 + nAdpcmSamplesProcessed = 0; + s5 = 0; if (nParts == 1) { samplesLenAdjusted = samplesLenFixedPoint >> 0x10; @@ -777,59 +449,37 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } if (curLoadedBook != audioBookSample->book->book) { - u32 nEntries; // v1 + u32 nEntries; curLoadedBook = audioBookSample->book->book; -#ifdef VERSION_EU nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors; aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook + noteSubEu->bookOffset)); -#else - nEntries = audioBookSample->book->order * audioBookSample->book->npredictors; - aLoadADPCM(cmd++, nEntries * 16, VIRTUAL_TO_PHYSICAL2(curLoadedBook)); -#endif } -#ifdef VERSION_EU if (noteSubEu->bookOffset) { curLoadedBook = euUnknownData_80301950; // what's this? never read } -#endif while (nAdpcmSamplesProcessed != samplesLenAdjusted) { - s32 samplesRemaining; // v1 + s32 samplesRemaining; s32 s0; noteFinished = FALSE; restart = FALSE; nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; -#ifdef VERSION_EU s2 = synthesisState->samplePosInt & 0xf; samplesRemaining = endPos - synthesisState->samplePosInt; -#else - s2 = note->samplePosInt & 0xf; - samplesRemaining = endPos - note->samplePosInt; -#endif -#ifdef VERSION_EU if (s2 == 0 && synthesisState->restart == FALSE) { s2 = 16; } -#else - if (s2 == 0 && note->restart == FALSE) { - s2 = 16; - } -#endif - s6 = 16 - s2; // a1 + s6 = 16 - s2; if (nSamplesToProcess < samplesRemaining) { t0 = (nSamplesToProcess - s6 + 0xf) / 16; s0 = t0 * 16; s3 = s6 + s0 - nSamplesToProcess; } else { -#ifndef VERSION_EU - s0 = samplesRemaining + s2 - 0x10; -#else s0 = samplesRemaining - s6; -#endif s3 = 0; if (s0 <= 0) { s0 = 0; @@ -845,7 +495,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } if (t0 != 0) { -#ifdef VERSION_EU temp = (synthesisState->samplePosInt - s2 + 0x10) / 16; if (audioBookSample->loaded == 0x81) { v0_2 = sampleAddr + temp * 9; @@ -854,12 +503,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { (uintptr_t) (sampleAddr + temp * 9), t0 * 9, flags, &synthesisState->sampleDmaIndex); } -#else - temp = (note->samplePosInt - s2 + 0x10) / 16; - v0_2 = dma_sample_data( - (uintptr_t) (sampleAddr + temp * 9), - t0 * 9, flags, ¬e->sampleDmaIndex); -#endif a3 = (u32)((uintptr_t) v0_2 & 0xf); aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA, 0, t0 * 9 + a3); aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3)); @@ -868,22 +511,13 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { a3 = 0; } -#ifdef VERSION_EU if (synthesisState->restart != FALSE) { aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); flags = A_LOOP; // = 2 synthesisState->restart = FALSE; } -#else - if (note->restart != FALSE) { - aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); - flags = A_LOOP; // = 2 - note->restart = FALSE; - } -#endif nSamplesInThisIteration = s0 + s6 - s3; -#ifdef VERSION_EU if (nAdpcmSamplesProcessed == 0) { aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); @@ -899,17 +533,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); } -#else - if (nAdpcmSamplesProcessed == 0) { - aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); - aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState)); - sp130 = s2 * 2; - } else { - aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5), s0 * 2); - aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState)); - aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5) + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); - } -#endif nAdpcmSamplesProcessed += nSamplesInThisIteration; @@ -936,32 +559,17 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { if (noteFinished) { aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); -#ifdef VERSION_EU noteSubEu->finished = 1; note->noteSubEu.finished = 1; note->noteSubEu.enabled = 0; -#else - note->samplePosInt = 0; - note->finished = 1; - ((struct vNote *)note)->enabled = 0; -#endif break; } -#ifdef VERSION_EU if (restart) { synthesisState->restart = TRUE; synthesisState->samplePosInt = loopInfo->start; } else { synthesisState->samplePosInt += nSamplesToProcess; } -#else - if (restart) { - note->restart = TRUE; - note->samplePosInt = loopInfo->start; - } else { - note->samplePosInt += nSamplesToProcess; - } -#endif } switch (nParts) { @@ -973,18 +581,10 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { switch (curPart) { case 0: aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED, samplesLenAdjusted + 4); -#ifdef VERSION_EU aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->dummyResampleState)); -#else - aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->dummyResampleState)); -#endif resampledTempLen = samplesLenAdjusted + 4; noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED + 4; -#ifdef VERSION_EU if (noteSubEu->finished != FALSE) { -#else - if (note->finished != FALSE) { -#endif aClearBuffer(cmd++, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10); } break; @@ -993,15 +593,9 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED2, samplesLenAdjusted + 8); -#ifdef VERSION_EU aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2( synthesisState->synthesisBuffers->dummyResampleState)); -#else - aResample(cmd++, A_INIT, 0xff60, - VIRTUAL_TO_PHYSICAL2( - note->synthesisBuffers->dummyResampleState)); -#endif aDMEMMove(cmd++, DMEM_ADDR_RESAMPLED2 + 4, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 4); @@ -1009,11 +603,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } } -#ifdef VERSION_EU if (noteSubEu->finished != FALSE) { -#else - if (note->finished != FALSE) { -#endif break; } } @@ -1021,7 +611,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { flags = 0; -#ifdef VERSION_EU if (noteSubEu->needsInit == TRUE) { flags = A_INIT; noteSubEu->needsInit = FALSE; @@ -1029,62 +618,25 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint, noteSamplesDmemAddrBeforeResampling, flags); -#else - if (note->needsInit == TRUE) { - flags = A_INIT; - note->needsInit = FALSE; - } - cmd = final_resample(cmd, note, bufLen * 2, resamplingRateFixedPoint, - noteSamplesDmemAddrBeforeResampling, flags); -#endif - -#ifdef VERSION_EU if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) { leftRight = 1; } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) { leftRight = 2; -#else - if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) { - leftRight = 1; - } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) { - leftRight = 2; -#endif } else { leftRight = 0; } -#ifdef VERSION_EU cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, 0, leftRight, flags); -#else - cmd = process_envelope(cmd, note, bufLen, 0, leftRight, flags); -#endif -#ifdef VERSION_EU if (noteSubEu->usesHeadsetPanEffects) { cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight); } -#else - if (note->usesHeadsetPanEffects) { - cmd = note_apply_headset_pan_effects(cmd, note, bufLen * 2, flags, leftRight); - } -#endif } -#ifndef VERSION_EU - } - - t9 = bufLen * 2; - aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); - aInterleave(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH); - t9 *= 2; - aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); - aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); -#endif return cmd; } -#ifdef VERSION_EU u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) { s32 a3; s32 repeats; @@ -1105,59 +657,13 @@ u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthes } return cmd; } -#else -u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { - s32 a3; - s32 i; - aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, - /*count*/ sizeof(note->synthesisBuffers->samples)); - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->samples)); - note->samplePosInt &= (note->sampleCount - 1); - a3 = 64 - note->samplePosInt; - if (a3 < nSamplesToLoad) { - for (i = 0; i <= (nSamplesToLoad - a3 + 63) / 64 - 1; i++) { - aDMEMMove(cmd++, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + (1 + i) * sizeof(note->synthesisBuffers->samples), /*count*/ sizeof(note->synthesisBuffers->samples)); - } - } - return cmd; -} -#endif -#ifdef VERSION_EU u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) { aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); return cmd; } -#else -u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags) { - aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); - aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->finalResampleState)); - return cmd; -} -#endif -#ifndef VERSION_EU -u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, - UNUSED u32 flags) { - UNUSED u8 pad[16]; - struct VolumeChange vol; - vol.sourceLeft = note->curVolLeft; - vol.sourceRight = note->curVolRight; - vol.targetLeft = note->targetVolLeft; - vol.targetRight = note->targetVolRight; - note->curVolLeft = vol.targetLeft; - note->curVolRight = vol.targetRight; - return process_envelope_inner(cmd, note, nSamples, inBuf, headsetPanSettings, &vol); -} - -u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, - s32 headsetPanSettings, struct VolumeChange *vol) { - UNUSED u8 pad[3]; - u8 mixerFlags; - UNUSED u8 pad2[8]; - s32 rampLeft, rampRight; -#elif defined(VERSION_EU) u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, UNUSED u32 flags) { UNUSED u8 pad1[20]; u16 sourceRight; @@ -1181,7 +687,6 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat } synthesisState->curVolLeft = targetLeft; synthesisState->curVolRight = targetRight; -#endif // For aEnvMixer, five buffers and count are set using aSetBuffer. // in, dry left, count without A_AUX flag. @@ -1227,49 +732,25 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat } } -#ifdef VERSION_EU if (targetLeft == sourceLeft && targetRight == sourceRight && !note->envMixerNeedsInit) { -#else - if (vol->targetLeft == vol->sourceLeft && vol->targetRight == vol->sourceRight - && !note->envMixerNeedsInit) { -#endif mixerFlags = A_CONTINUE; } else { mixerFlags = A_INIT; -#ifdef VERSION_EU rampLeft = gCurrentLeftVolRamping[targetLeft >> 5] * gCurrentRightVolRamping[sourceLeft >> 5]; rampRight = gCurrentLeftVolRamping[targetRight >> 5] * gCurrentRightVolRamping[sourceRight >> 5]; -#else - rampLeft = get_volume_ramping(vol->sourceLeft, vol->targetLeft, nSamples); - rampRight = get_volume_ramping(vol->sourceRight, vol->targetRight, nSamples); -#endif // The operation's parameters change meanings depending on flags -#ifdef VERSION_EU aSetVolume(cmd++, A_VOL | A_LEFT, sourceLeft, 0, 0); aSetVolume(cmd++, A_VOL | A_RIGHT, sourceRight, 0, 0); aSetVolume32(cmd++, A_RATE | A_LEFT, targetLeft, rampLeft); aSetVolume32(cmd++, A_RATE | A_RIGHT, targetRight, rampRight); aSetVolume(cmd++, A_AUX, gVolume, 0, note->reverbVol << 8); -#else - aSetVolume(cmd++, A_VOL | A_LEFT, vol->sourceLeft, 0, 0); - aSetVolume(cmd++, A_VOL | A_RIGHT, vol->sourceRight, 0, 0); - aSetVolume32(cmd++, A_RATE | A_LEFT, vol->targetLeft, rampLeft); - aSetVolume32(cmd++, A_RATE | A_RIGHT, vol->targetRight, rampRight); - aSetVolume(cmd++, A_AUX, gVolume, 0, note->reverbVolShifted); -#endif } -#ifdef VERSION_EU if (gUseReverb && note->reverbVol != 0) { aEnvMixer(cmd++, mixerFlags | A_AUX, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->mixEnvelopeState)); -#else - if (gSynthesisReverb.useReverb && note->reverbVol != 0) { - aEnvMixer(cmd++, mixerFlags | A_AUX, - VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); -#endif if (note->stereoStrongRight) { aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); // 0x8000 is -100%, so subtract sound instead of adding... @@ -1285,11 +766,7 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat /*out*/ DMEM_ADDR_WET_RIGHT_CH); } } else { -#ifdef VERSION_EU aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->mixEnvelopeState)); -#else - aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); -#endif if (note->stereoStrongRight) { aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_DRY, @@ -1303,41 +780,24 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat return cmd; } -#ifdef VERSION_EU u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight) { -#else -u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight) { -#endif u16 dest; u16 pitch; -#ifdef VERSION_EU u8 prevPanShift; u8 panShift; UNUSED u8 unkDebug; -#else - u16 prevPanShift; - u16 panShift; -#endif switch (leftRight) { case 1: dest = DMEM_ADDR_LEFT_CH; -#ifdef VERSION_EU panShift = noteSubEu->headsetPanRight; -#else - panShift = note->headsetPanRight; -#endif note->prevHeadsetPanLeft = 0; prevPanShift = note->prevHeadsetPanRight; note->prevHeadsetPanRight = panShift; break; case 2: dest = DMEM_ADDR_RIGHT_CH; -#ifdef VERSION_EU panShift = noteSubEu->headsetPanLeft; -#else - panShift = note->headsetPanLeft; -#endif note->prevHeadsetPanRight = 0; prevPanShift = note->prevHeadsetPanLeft; @@ -1359,13 +819,9 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, 32); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); -#ifdef VERSION_EU pitch = (bufLen << 0xf) / (bufLen + panShift - prevPanShift + 8); if (pitch) { } -#else - pitch = (bufLen << 0xf) / (panShift + bufLen - prevPanShift + 8); -#endif aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP + 8, DMEM_ADDR_TEMP, panShift + bufLen - prevPanShift); aResample(cmd++, 0, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); } else { @@ -1375,8 +831,8 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 pitch = (bufLen << 0xf) / (bufLen + panShift - prevPanShift); } -#if defined(VERSION_EU) && !defined(AVOID_UB) - if (unkDebug) { // UB +#ifndef AVOID_UB + if (unkDebug) { } #endif aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, panShift + bufLen - prevPanShift); @@ -1408,134 +864,3 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 return cmd; } - -#ifndef VERSION_EU -// Moved to playback.c in EU - -void note_init_volume(struct Note *note) { - note->targetVolLeft = 0; - note->targetVolRight = 0; - note->reverbVol = 0; - note->reverbVolShifted = 0; - note->unused2 = 0; - note->curVolLeft = 1; - note->curVolRight = 1; - note->frequency = 0.0f; -} - -void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol) { - s32 panIndex; - f32 volLeft; - f32 volRight; - // Anding with 127 avoids out-of-bounds reads when pan is outside of [0, 1]. - // This can occur during PU movement -- see the bug comment in get_sound_pan - // in external.c. An out-of-bounds read by itself doesn't crash, but if the - // resulting value is a nan or denormal, performing arithmetic on it crashes - // on console. -#ifdef VERSION_JP - panIndex = MIN((s32)(pan * 127.5), 127); -#else - panIndex = (s32)(pan * 127.5f) & 127; -#endif - if (note->stereoHeadsetEffects && gSoundMode == SOUND_MODE_HEADSET) { - s8 smallPanIndex; - s8 temp = (s8)(pan * 10.0f); - if (temp < 9) { - smallPanIndex = temp; - } else { - smallPanIndex = 9; - } - note->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; - note->headsetPanRight = gHeadsetPanQuantization[9 - smallPanIndex]; - note->stereoStrongRight = FALSE; - note->stereoStrongLeft = FALSE; - note->usesHeadsetPanEffects = TRUE; - volLeft = gHeadsetPanVolume[panIndex]; - volRight = gHeadsetPanVolume[127 - panIndex]; - } else if (note->stereoHeadsetEffects && gSoundMode == SOUND_MODE_STEREO) { - u8 strongLeft; - u8 strongRight; - strongLeft = FALSE; - strongRight = FALSE; - note->headsetPanLeft = 0; - note->headsetPanRight = 0; - note->usesHeadsetPanEffects = FALSE; - volLeft = gStereoPanVolume[panIndex]; - volRight = gStereoPanVolume[127 - panIndex]; - if (panIndex < 0x20) { - strongLeft = TRUE; - } else if (panIndex > 0x60) { - strongRight = TRUE; - } - note->stereoStrongRight = strongRight; - note->stereoStrongLeft = strongLeft; - } else if (gSoundMode == SOUND_MODE_MONO) { - volLeft = .707f; - volRight = .707f; - } else { - volLeft = gDefaultPanVolume[panIndex]; - volRight = gDefaultPanVolume[127 - panIndex]; - } - - if (velocity < 0) { - velocity = 0; - } -#ifdef VERSION_JP - note->targetVolLeft = (u16)(velocity * volLeft) & ~0x80FF; // 0x7F00, but that doesn't match - note->targetVolRight = (u16)(velocity * volRight) & ~0x80FF; -#else - note->targetVolLeft = (u16)(s32)(velocity * volLeft) & ~0x80FF; - note->targetVolRight = (u16)(s32)(velocity * volRight) & ~0x80FF; -#endif - if (note->targetVolLeft == 0) { - note->targetVolLeft++; - } - if (note->targetVolRight == 0) { - note->targetVolRight++; - } - if (note->reverbVol != reverbVol) { - note->reverbVol = reverbVol; - note->reverbVolShifted = reverbVol << 8; - note->envMixerNeedsInit = TRUE; - return; - } - - if (note->needsInit) { - note->envMixerNeedsInit = TRUE; - } else { - note->envMixerNeedsInit = FALSE; - } -} - -void note_set_frequency(struct Note *note, f32 frequency) { - note->frequency = frequency; -} - -void note_enable(struct Note *note) { - note->enabled = TRUE; - note->needsInit = TRUE; - note->restart = FALSE; - note->finished = FALSE; - note->stereoStrongRight = FALSE; - note->stereoStrongLeft = FALSE; - note->usesHeadsetPanEffects = FALSE; - note->headsetPanLeft = 0; - note->headsetPanRight = 0; - note->prevHeadsetPanRight = 0; - note->prevHeadsetPanLeft = 0; -} - -void note_disable(struct Note *note) { - if (note->needsInit == TRUE) { - note->needsInit = FALSE; - } else { - note_set_vel_pan_reverb(note, 0, .5, 0); - } - note->priority = NOTE_PRIORITY_DISABLED; - note->enabled = FALSE; - note->finished = FALSE; - note->parentLayer = NO_LAYER; - note->prevParentLayer = NO_LAYER; -} -#endif -#endif diff --git a/src/audio/eu/synthesis.h b/src/audio/eu/synthesis.h new file mode 100644 index 00000000..7e86dfe9 --- /dev/null +++ b/src/audio/eu/synthesis.h @@ -0,0 +1,58 @@ +#ifndef AUDIO_SYNTHESIS_H +#define AUDIO_SYNTHESIS_H + +#include "internal.h" + +#define DEFAULT_LEN_1CH 0x140 +#define DEFAULT_LEN_2CH 0x280 + +#define MAX_UPDATES_PER_FRAME 5 + +struct ReverbRingBufferItem { + s16 numSamplesAfterDownsampling; + s16 chunkLen; // never read + s16 *toDownsampleLeft; + s16 *toDownsampleRight; // data pointed to by left and right are adjacent in memory + s32 startPos; // start pos in ring buffer + s16 lengthA; // first length in ring buffer (from startPos, at most until end) + s16 lengthB; // second length in ring buffer (from pos 0) +}; // size = 0x14 + +struct SynthesisReverb { + /*0x00, 0x00, 0x00*/ u8 resampleFlags; + /*0x01, 0x01, 0x01*/ u8 useReverb; + /*0x02, 0x02, 0x02*/ u8 framesLeftToIgnore; + /*0x03, 0x03, 0x03*/ u8 curFrame; + /* 0x04, 0x04*/ u8 downsampleRate; + /* 0x06, 0x06*/ u16 windowSize; // same as bufSizePerChannel + /*0x04, 0x08, 0x0A*/ u16 reverbGain; + /*0x06, 0x0A, 0x0C*/ u16 resampleRate; + /*0x08, 0x0C, 0x14*/ s32 nextRingBufferPos; + /*0x0C, 0x10, 0x18*/ s32 unkC; // never read + /*0x10, 0x14, 0x1C*/ s32 bufSizePerChannel; + struct { + s16 *left; + s16 *right; + } ringBuffer; + /*0x1C, 0x20, 0x28*/ s16 *resampleStateLeft; + /*0x20, 0x24, 0x2C*/ s16 *resampleStateRight; + /*0x24, 0x28, 0x30*/ s16 *unk24; // never read + /*0x28, 0x2C, 0x34*/ s16 *unk28; // never read + /*0x2C, 0x30, 0x38*/ struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME]; + // Only used in sh: + /* 0x100*/ s16 *unk100; + /* 0x104*/ s16 *unk104; + /* 0x108*/ s16 *unk108; + /* 0x10C*/ s16 *unk10C; +}; // 0xCC <= size <= 0x100 +extern struct SynthesisReverb gSynthesisReverbs[4]; +extern s8 gNumSynthesisReverbs; +extern struct NoteSubEu *gNoteSubsEu; +extern f32 gLeftVolRampings[3][1024]; +extern f32 gRightVolRampings[3][1024]; +extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above +extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above + +u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen); + +#endif // AUDIO_SYNTHESIS_H diff --git a/src/audio/external.c b/src/audio/external.c index a5140d76..fc8b5905 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -1,12 +1,30 @@ #include #include "sm64.h" -#include "heap.h" -#include "load.h" -#include "data.h" -#include "seqplayer.h" +#if defined(VERSION_US) || defined(VERSION_JP) +#include "us_jp/heap.h" +#include "us_jp/load.h" +#include "us_jp/data.h" +#include "us_jp/seqplayer.h" +#include "us_jp/playback.h" +#include "us_jp/synthesis.h" +#elif defined(VERSION_EU) +#include "eu/port.h" +#include "eu/heap.h" +#include "eu/load.h" +#include "eu/data.h" +#include "eu/seqplayer.h" +#include "eu/playback.h" +#include "eu/synthesis.h" +#else +#include "sh/port.h" +#include "sh/heap.h" +#include "sh/load.h" +#include "sh/data.h" +#include "sh/seqplayer.h" +#include "sh/playback.h" +#include "sh/synthesis.h" +#endif #include "external.h" -#include "playback.h" -#include "synthesis.h" #include "game/level_update.h" #include "game/object_list_processor.h" #include "game/camera.h" @@ -259,7 +277,7 @@ u16 sLevelAcousticReaches[LEVEL_COUNT] = { #undef STUB_LEVEL #undef DEFINE_LEVEL -#define AUDIO_MAX_DISTANCE US_FLOAT(22000.0) +#define AUDIO_MAX_DISTANCE JP_DOUBLE(22000.0) #ifdef VERSION_JP #define LOW_VOLUME_REVERB 48.0 @@ -374,7 +392,9 @@ s32 D_SH_80343CF0; s8 D_SH_80343CF8_pad[0x8]; struct UnkStruct80343D00 D_SH_80343D00; s8 D_SH_8034DC8_pad[0x8]; -OSPiHandle DriveRomHandle; // used in osDriveRomInit.c. Why here? +#ifndef LIBULTRA_EXCLUSIVE +ALIGNED8 OSPiHandle DriveRomHandle; // used in osDriveRomInit.c. Why here? +#endif s8 D_SH_80343E48_pad[0x8]; #endif @@ -402,23 +422,17 @@ s32 unk_sh_8034754C; #endif #ifdef VERSION_EU -OSMesgQueue OSMesgQueue0; -OSMesgQueue OSMesgQueue1; -OSMesgQueue OSMesgQueue2; -OSMesgQueue OSMesgQueue3; -extern OSMesgQueue *OSMesgQueues[]; +OSMesgQueue OSMesgQueue0Data; +OSMesgQueue OSMesgQueue1Data; +OSMesgQueue OSMesgQueue2Data; +OSMesgQueue OSMesgQueue3Data; struct EuAudioCmd sAudioCmd[0x100]; -OSMesg OSMesg0; -s32 pad1; // why is there 1 s32 here -OSMesg OSMesg1; -s32 pad2[2]; // it's not just that the struct is bigger than we think, because there are 2 here -OSMesg OSMesg2; // and none here. wth nintendo -OSMesg OSMesg3; -#else // VERSION_SH -extern OSMesgQueue *D_SH_80350F88; -extern OSMesgQueue *D_SH_80350FA8; +OSMesg OSMesg0[1]; +OSMesg OSMesg1[4]; +OSMesg OSMesg2[1]; +OSMesg OSMesg3[1]; #endif #ifdef VERSION_JP @@ -427,11 +441,6 @@ typedef u16 FadeT; typedef s32 FadeT; #endif -// some sort of main thread -> sound thread dispatchers -extern void func_802ad728(u32 bits, f32 arg); -extern void func_802ad74c(u32 bits, u32 arg); -extern void func_802ad770(u32 bits, s8 arg); - static void update_background_music_after_sound(u8 bank, u8 soundIndex); static void update_game_sound(void); static void fade_channel_volume_scale(u8 player, u8 channelId, u8 targetScale, u16 fadeTimer); @@ -521,22 +530,12 @@ const char unusedErrorStr2[] = "specchg error\n"; #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) void audio_reset_session_eu(s32 presetId) { OSMesg mesg; -#if defined(VERSION_SH) || defined(VERSION_CN) - osRecvMesg(D_SH_80350FA8, &mesg, OS_MESG_NOBLOCK); - osSendMesg(D_SH_80350F88, (OSMesg) presetId, OS_MESG_NOBLOCK); - osRecvMesg(D_SH_80350FA8, &mesg, OS_MESG_BLOCK); + osRecvMesg(OSMesgQueue3, &mesg, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueue2, (OSMesg) presetId, OS_MESG_NOBLOCK); + osRecvMesg(OSMesgQueue3, &mesg, OS_MESG_BLOCK); if ((s32) mesg != presetId) { - osRecvMesg(D_SH_80350FA8, &mesg, OS_MESG_BLOCK); + osRecvMesg(OSMesgQueue3, &mesg, OS_MESG_BLOCK); } - -#else - osRecvMesg(OSMesgQueues[3], &mesg, OS_MESG_NOBLOCK); - osSendMesg(OSMesgQueues[2], (OSMesg) presetId, OS_MESG_NOBLOCK); - osRecvMesg(OSMesgQueues[3], &mesg, OS_MESG_BLOCK); - if ((s32) mesg != presetId) { - osRecvMesg(OSMesgQueues[3], &mesg, OS_MESG_BLOCK); - } -#endif } #endif @@ -673,11 +672,6 @@ static void seq_player_fade_to_target_volume(s32 player, FadeT fadeDuration, u8 } #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#ifdef VERSION_EU -extern void func_802ad7a0(void); -#else -extern void func_sh_802F64C8(void); -#endif /** * Called from threads: thread5_game_loop @@ -687,17 +681,13 @@ void maybe_tick_game_sound(void) { update_game_sound(); sGameLoopTicked = 0; } -#ifdef VERSION_EU func_802ad7a0(); -#else - func_sh_802F64C8(); // moved in SH -#endif } void func_eu_802e9bec(s32 player, s32 channel, s32 arg2) { // EU verson of unused_803209D8 // chan->stopSomething2 = arg2? - func_802ad770(0x08000000 | (player & 0xff) << 16 | (channel & 0xff) << 8, (s8) arg2); + port_cmd_s8(0x08000000 | (player & 0xff) << 16 | (channel & 0xff) << 8, (s8) arg2); } #else @@ -1031,7 +1021,7 @@ static void select_current_sounds(u8 bank) { } else if (*sSoundBanks[bank][soundIndex].z > 0.0f) { sSoundBanks[bank][soundIndex].priority = (u32) sSoundBanks[bank][soundIndex].distance - + (u32)(*sSoundBanks[bank][soundIndex].z / US_FLOAT(6.0)) + + (u32)(*sSoundBanks[bank][soundIndex].z / JP_DOUBLE(6.0)) + 0x4c * (0xff - requestedPriority); } else { sSoundBanks[bank][soundIndex].priority = @@ -1181,15 +1171,15 @@ static f32 get_sound_pan(f32 x, f32 z) { // 2. far right pan: between 1:30 and 4:30 // 3. far left pan: between 7:30 and 10:30 // 4. center pan: between 4:30 and 7:30 or between 10:30 and 1:30 - if (x == US_FLOAT(0.0) && z == US_FLOAT(0.0)) { + if (x == JP_DOUBLE(0.0) && z == JP_DOUBLE(0.0)) { // x and z being 0 results in a center pan - pan = US_FLOAT(0.5); - } else if (x >= US_FLOAT(0.0) && absX >= absZ) { + pan = JP_DOUBLE(0.5); + } else if (x >= JP_DOUBLE(0.0) && absX >= absZ) { // far right pan - pan = US_FLOAT(1.0) - (2 * AUDIO_MAX_DISTANCE - absX) / (US_FLOAT(3.0) * (2 * AUDIO_MAX_DISTANCE - absZ)); + pan = JP_DOUBLE(1.0) - (2 * AUDIO_MAX_DISTANCE - absX) / (JP_DOUBLE(3.0) * (2 * AUDIO_MAX_DISTANCE - absZ)); } else if (x < 0 && absX > absZ) { // far left pan - pan = (2 * AUDIO_MAX_DISTANCE - absX) / (US_FLOAT(3.0) * (2 * AUDIO_MAX_DISTANCE - absZ)); + pan = (2 * AUDIO_MAX_DISTANCE - absX) / (JP_DOUBLE(3.0) * (2 * AUDIO_MAX_DISTANCE - absZ)); } else { // center pan //! @bug (JP PU sound glitch) If |x|, |z| > AUDIO_MAX_DISTANCE, we'll @@ -1197,7 +1187,7 @@ static f32 get_sound_pan(f32 x, f32 z) { // since x is not clamped. On JP, this can lead to an out-of-bounds // float read in note_set_vel_pan_reverb when x is highly negative, // causing console crashes when that float is a nan or denormal. - pan = 0.5 + x / (US_FLOAT(6.0) * absZ); + pan = 0.5 + x / (JP_DOUBLE(6.0) * absZ); } return pan; @@ -1249,7 +1239,7 @@ static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) { if (intensity >= 0.08f) #endif { - intensity -= (f32)(gAudioRandom & 0xf) / US_FLOAT(192.0); + intensity -= (f32)(gAudioRandom & 0xf) / JP_DOUBLE(192.0); } } } else { @@ -1269,7 +1259,7 @@ static f32 get_sound_freq_scale(u8 bank, u8 item) { if (!(sSoundBanks[bank][item].soundBits & SOUND_CONSTANT_FREQUENCY)) { amount = sSoundBanks[bank][item].distance / AUDIO_MAX_DISTANCE; if (sSoundBanks[bank][item].soundBits & SOUND_VIBRATO) { - amount += (f32)(gAudioRandom & 0xff) / US_FLOAT(64.0); + amount += (f32)(gAudioRandom & 0xff) / JP_DOUBLE(64.0); } } else { amount = 0.0f; @@ -1277,7 +1267,7 @@ static f32 get_sound_freq_scale(u8 bank, u8 item) { // Goes from 1 at the camera to 1 + 1/15 at AUDIO_MAX_DISTANCE (and continues rising // farther than that) - return amount / US_FLOAT(15.0) + US_FLOAT(1.0); + return amount / JP_DOUBLE(15.0) + JP_DOUBLE(1.0); } /** @@ -1309,7 +1299,7 @@ static u8 get_sound_reverb(UNUSED u8 bank, UNUSED u8 soundIndex, u8 channelIndex // LOW_VOLUME_REVERB when the volume is 0 reverb = (u8)((u8) gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[5] + sLevelAreaReverbs[level][area] - + (US_FLOAT(1.0) - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume) + + (JP_DOUBLE(1.0) - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume) * LOW_VOLUME_REVERB); if (reverb > 0x7f) { @@ -1388,7 +1378,7 @@ static void update_game_sound(void) { if (!(sSoundBanks[bank][soundIndex].soundBits & SOUND_CONSTANT_FREQUENCY)) { if (sSoundMovingSpeed[bank] > 8) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728( + port_cmd_f32( 0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK1)); #else @@ -1398,7 +1388,7 @@ static void update_game_sound(void) { #endif } else { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK1) * ((sSoundMovingSpeed[bank] + 8.0f) / 16)); #else @@ -1408,7 +1398,7 @@ static void update_game_sound(void) { #endif } #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), get_sound_pan(*sSoundBanks[bank][soundIndex].x, *sSoundBanks[bank][soundIndex].z)); #else @@ -1420,29 +1410,29 @@ static void update_game_sound(void) { if ((sSoundBanks[bank][soundIndex].soundBits & SOUNDARGS_MASK_SOUNDID) == (SOUND_MOVING_FLYING & SOUNDARGS_MASK_SOUNDID)) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728( + port_cmd_f32( 0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex) - + ((f32) sSoundMovingSpeed[bank] / US_FLOAT(80.0))); + + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(80.0))); #else value = get_sound_freq_scale(bank, soundIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->freqScale = - ((f32) sSoundMovingSpeed[bank] / US_FLOAT(80.0)) + value; + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(80.0)) + value; #endif } else { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728( + port_cmd_f32( 0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex) - + ((f32) sSoundMovingSpeed[bank] / US_FLOAT(400.0))); + + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(400.0))); #else value = get_sound_freq_scale(bank, soundIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->freqScale = - ((f32) sSoundMovingSpeed[bank] / US_FLOAT(400.0)) + value; + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(400.0)) + value; #endif } #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = @@ -1454,9 +1444,9 @@ static void update_game_sound(void) { // fallthrough case SOUND_BANK_MENU: #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), 1); - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), 64); - func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), 1); + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), 64); + port_cmd_f32(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume = 1.0f; @@ -1467,16 +1457,16 @@ static void update_game_sound(void) { case SOUND_BANK_ACTION: case SOUND_BANK_VOICE: #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK1)); - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), get_sound_pan(*sSoundBanks[bank][soundIndex].x, *sSoundBanks[bank][soundIndex].z) * 127.0f + 0.5f); - func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume = @@ -1497,16 +1487,16 @@ static void update_game_sound(void) { case SOUND_BANK_GENERAL2: case SOUND_BANK_OBJ2: #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK2)); - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), get_sound_pan(*sSoundBanks[bank][soundIndex].x, *sSoundBanks[bank][soundIndex].z) * 127.0f + 0.5f); - func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = @@ -1572,7 +1562,7 @@ static void update_game_sound(void) { if (!(sSoundBanks[bank][soundIndex].soundBits & SOUND_CONSTANT_FREQUENCY)) { if (sSoundMovingSpeed[bank] > 8) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728( + port_cmd_f32( 0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK1)); #else @@ -1582,7 +1572,7 @@ static void update_game_sound(void) { #endif } else { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK1) * ((sSoundMovingSpeed[bank] + 8.0f) / 16)); #else @@ -1592,7 +1582,7 @@ static void update_game_sound(void) { #endif } #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), get_sound_pan(*sSoundBanks[bank][soundIndex].x, *sSoundBanks[bank][soundIndex].z)); #else @@ -1604,29 +1594,29 @@ static void update_game_sound(void) { if ((sSoundBanks[bank][soundIndex].soundBits & SOUNDARGS_MASK_SOUNDID) == (SOUND_MOVING_FLYING & SOUNDARGS_MASK_SOUNDID)) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728( + port_cmd_f32( 0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex) - + ((f32) sSoundMovingSpeed[bank] / US_FLOAT(80.0))); + + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(80.0))); #else value = get_sound_freq_scale(bank, soundIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->freqScale = - ((f32) sSoundMovingSpeed[bank] / US_FLOAT(80.0)) + value; + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(80.0)) + value; #endif } else { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728( + port_cmd_f32( 0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex) - + ((f32) sSoundMovingSpeed[bank] / US_FLOAT(400.0))); + + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(400.0))); #else value = get_sound_freq_scale(bank, soundIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->freqScale = - ((f32) sSoundMovingSpeed[bank] / US_FLOAT(400.0)) + value; + ((f32) sSoundMovingSpeed[bank] / JP_DOUBLE(400.0)) + value; #endif } #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = @@ -1638,9 +1628,9 @@ static void update_game_sound(void) { // fallthrough case SOUND_BANK_MENU: #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), 1); - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), 64); - func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), 1); + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), 64); + port_cmd_f32(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume = 1.0f; @@ -1651,16 +1641,16 @@ static void update_game_sound(void) { case SOUND_BANK_ACTION: case SOUND_BANK_VOICE: #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK1)); - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), get_sound_pan(*sSoundBanks[bank][soundIndex].x, *sSoundBanks[bank][soundIndex].z) * 127.0f + 0.5f); - func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume = @@ -1681,16 +1671,16 @@ static void update_game_sound(void) { case SOUND_BANK_GENERAL2: case SOUND_BANK_OBJ2: #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); - func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x02020000 | ((channelIndex & 0xff) << 8), get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK2)); - func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + port_cmd_s8(0x03020000 | ((channelIndex & 0xff) << 8), get_sound_pan(*sSoundBanks[bank][soundIndex].x, *sSoundBanks[bank][soundIndex].z) * 127.0f + 0.5f); - func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + port_cmd_f32(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = @@ -1738,13 +1728,13 @@ static void seq_player_play_sequence(u8 player, u8 seqId, u16 arg2) { } #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad770(0x46000000 | ((u8)(u32) player) << 16, seqId & SEQ_VARIATION); - func_802ad74c(0x82000000 | ((u8)(u32) player) << 16 | ((u8)(seqId & SEQ_BASE_ID)) << 8, arg2); + port_cmd_s8(0x46000000 | ((u8)(u32) player) << 16, seqId & SEQ_VARIATION); + port_cmd_u32(0x82000000 | ((u8)(u32) player) << 16 | ((u8)(seqId & SEQ_BASE_ID)) << 8, arg2); if (player == SEQ_PLAYER_LEVEL) { targetVolume = begin_background_music_fade(0); if (targetVolume != 0xff) { - gSequencePlayers[SEQ_PLAYER_LEVEL].fadeVolumeScale = (f32) targetVolume / US_FLOAT(127.0); + gSequencePlayers[SEQ_PLAYER_LEVEL].fadeVolumeScale = (f32) targetVolume / JP_DOUBLE(127.0); } } #else @@ -1756,7 +1746,7 @@ static void seq_player_play_sequence(u8 player, u8 seqId, u16 arg2) { targetVolume = begin_background_music_fade(0); if (targetVolume != 0xff) { gSequencePlayers[SEQ_PLAYER_LEVEL].state = SEQUENCE_PLAYER_STATE_4; - gSequencePlayers[SEQ_PLAYER_LEVEL].fadeVolume = (f32) targetVolume / US_FLOAT(127.0); + gSequencePlayers[SEQ_PLAYER_LEVEL].fadeVolume = (f32) targetVolume / JP_DOUBLE(127.0); } } else { func_8031D690(player, arg2); @@ -1772,12 +1762,12 @@ void seq_player_fade_out(u8 player, u16 fadeDuration) { #ifdef VERSION_EU u32 fd = fadeDuration; #else - s32 fd = fadeDuration; // will also match if we change function signature func_802ad74c to use s32 as arg1 + s32 fd = fadeDuration; // will also match if we change function signature port_cmd_u32 to use s32 as arg1 #endif if (!player) { sCurrentBackgroundMusicSeqId = SEQUENCE_NONE; } - func_802ad74c(0x83000000 | (player & 0xff) << 16, fd); + port_cmd_u32(0x83000000 | (player & 0xff) << 16, fd); #else if (player == SEQ_PLAYER_LEVEL) { sCurrentBackgroundMusicSeqId = SEQUENCE_NONE; @@ -1805,7 +1795,7 @@ static void fade_channel_volume_scale(u8 player, u8 channelIndex, u8 targetScale if (gSequencePlayers[player].channels[channelIndex] != &gSequenceChannelNone) { temp = &D_80360928[player][channelIndex]; temp->remainingFrames = fadeDuration; - temp->velocity = ((f32)(targetScale / US_FLOAT(127.0)) + temp->velocity = ((f32)(targetScale / JP_DOUBLE(127.0)) - gSequencePlayers[player].channels[channelIndex]->volumeScale) / fadeDuration; temp->target = targetScale; @@ -1825,7 +1815,7 @@ static void func_8031F96C(u8 player) { && D_80360928[player][i].remainingFrames != 0) { D_80360928[player][i].current += D_80360928[player][i].velocity; #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, + port_cmd_f32(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, D_80360928[player][i].current); #else gSequencePlayers[player].channels[i]->volumeScale = D_80360928[player][i].current; @@ -1833,10 +1823,10 @@ static void func_8031F96C(u8 player) { D_80360928[player][i].remainingFrames--; if (D_80360928[player][i].remainingFrames == 0) { #if defined(VERSION_EU) - func_802ad728(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, + port_cmd_f32(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, FLOAT_CAST(D_80360928[player][i].target) / 127.0); #elif defined(VERSION_SH) || defined(VERSION_CN) - func_802ad728(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, + port_cmd_f32(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, FLOAT_CAST(D_80360928[player][i].target) / 127.0f); #else gSequencePlayers[player].channels[i]->volumeScale = @@ -2000,10 +1990,10 @@ void unused_8031FED0(u8 player, u32 bits, s8 arg2) { if ((bits & 3) == 0) { gSequencePlayers[player].channels[i]->volumeScale = 1.0f; } else if ((bits & 1) != 0) { - gSequencePlayers[player].channels[i]->volumeScale = (f32) arg2 / US_FLOAT(127.0); + gSequencePlayers[player].channels[i]->volumeScale = (f32) arg2 / JP_DOUBLE(127.0); } else { gSequencePlayers[player].channels[i]->volumeScale = - US_FLOAT(1.0) - (f32) arg2 / US_FLOAT(127.0); + JP_DOUBLE(1.0) - (f32) arg2 / JP_DOUBLE(127.0); } } bits >>= 2; @@ -2111,9 +2101,9 @@ void set_audio_muted(u8 muted) { for (i = 0; i < SEQUENCE_PLAYERS; i++) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (muted) { - func_802ad74c(0xf1000000, 0); + port_cmd_u32(0xf1000000, 0); } else { - func_802ad74c(0xf2000000, 0); + port_cmd_u32(0xf2000000, 0); } #else gSequencePlayers[i].muted = muted; @@ -2578,7 +2568,7 @@ void func_803210D4(u16 fadeDuration) { if (gSequencePlayers[SEQ_PLAYER_LEVEL].enabled == TRUE) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad74c(0x83000000, fadeDuration); + port_cmd_u32(0x83000000, fadeDuration); #else seq_player_fade_to_zero_volume(SEQ_PLAYER_LEVEL, fadeDuration); #endif @@ -2586,7 +2576,7 @@ void func_803210D4(u16 fadeDuration) { if (gSequencePlayers[SEQ_PLAYER_ENV].enabled == TRUE) { #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - func_802ad74c(0x83010000, fadeDuration); + port_cmd_u32(0x83010000, fadeDuration); #else seq_player_fade_to_zero_volume(SEQ_PLAYER_ENV, fadeDuration); #endif @@ -2706,7 +2696,7 @@ void sound_reset(u8 presetId) { disable_all_sequence_players(); sound_init(); #if defined(VERSION_SH) || defined(VERSION_CN) - func_802ad74c(0xF2000000, 0); + port_cmd_u32(0xF2000000, 0); #endif #if defined(VERSION_JP) || defined(VERSION_US) audio_reset_session(&gAudioSessionPresets[presetId]); diff --git a/src/audio/external.h b/src/audio/external.h index d2e59b1a..eef059ba 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -18,7 +18,6 @@ #define SEQ_PLAYER_ENV 1 // Misc music like the puzzle jingle #define SEQ_PLAYER_SFX 2 // Sound effects -extern s32 gAudioErrorFlags; extern f32 gGlobalSoundSource[3]; // defined in data.c, used by the game @@ -63,9 +62,4 @@ void audio_set_sound_mode(u8 arg0); void audio_init(void); // in load.c -#if defined(VERSION_EU) || defined(VERSION_SH) -struct SPTask *unused_80321460(); -struct SPTask *unused_80321460(void); -#endif - #endif // AUDIO_EXTERNAL_H diff --git a/src/audio/internal.h b/src/audio/internal.h deleted file mode 100644 index 1ca40b06..00000000 --- a/src/audio/internal.h +++ /dev/null @@ -1,855 +0,0 @@ -#ifndef AUDIO_INTERNAL_H -#define AUDIO_INTERNAL_H - -#include - -#include "types.h" - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#define SEQUENCE_PLAYERS 4 -#define SEQUENCE_CHANNELS 48 -#define SEQUENCE_LAYERS 64 -#else -#define SEQUENCE_PLAYERS 3 -#define SEQUENCE_CHANNELS 32 -#ifdef VERSION_JP -#define SEQUENCE_LAYERS 48 -#else -#define SEQUENCE_LAYERS 52 -#endif -#endif - -#define LAYERS_MAX 4 -#define CHANNELS_MAX 16 - -#define NO_LAYER ((struct SequenceChannelLayer *)(-1)) - -#define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts -#define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing -#define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half - -#define SEQUENCE_PLAYER_STATE_0 0 -#define SEQUENCE_PLAYER_STATE_FADE_OUT 1 -#define SEQUENCE_PLAYER_STATE_2 2 -#define SEQUENCE_PLAYER_STATE_3 3 -#define SEQUENCE_PLAYER_STATE_4 4 - -#define NOTE_PRIORITY_DISABLED 0 -#define NOTE_PRIORITY_STOPPING 1 -#define NOTE_PRIORITY_MIN 2 -#define NOTE_PRIORITY_DEFAULT 3 - -#define TATUMS_PER_BEAT 48 - -// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing -#define CODEC_ADPCM 0 -#define CODEC_S8 1 -#define CODEC_SKIP 2 - -#ifdef VERSION_JP -#define TEMPO_SCALE 1 -#else -#define TEMPO_SCALE TATUMS_PER_BEAT -#endif - -// TODO: US_FLOAT should probably be renamed to JP_DOUBLE since eu seems to use floats too -#ifdef VERSION_JP -#define US_FLOAT(x) x -#else -#define US_FLOAT(x) x ## f -#endif - -// Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion, -// resulting in more bloated codegen, while on US it goes through s32. -// Since u8 and u16 fit losslessly in both, behavior is the same. -#ifdef VERSION_JP -#define FLOAT_CAST(x) (f32) (x) -#else -#define FLOAT_CAST(x) (f32) (s32) (x) -#endif - -// No-op printf macro which leaves string literals in rodata in IDO. IDO -// doesn't support variadic macros, so instead we let the parameter list -// expand to a no-op comma expression. Another possibility is that it might -// have expanded to something with "if (0)". See also goddard/gd_main.h. -// On US/JP, -sopt optimizes away these except for external.c. -#ifdef __sgi -#define stubbed_printf -#else -#define stubbed_printf(...) -#endif - -#ifdef VERSION_EU -#define eu_stubbed_printf_0(msg) stubbed_printf(msg) -#define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a) -#define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b) -#define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c) -#else -#define eu_stubbed_printf_0(msg) -#define eu_stubbed_printf_1(msg, a) -#define eu_stubbed_printf_2(msg, a, b) -#define eu_stubbed_printf_3(msg, a, b, c) -#endif - -struct NotePool; - -struct AudioListItem { - // A node in a circularly linked list. Each node is either a head or an item: - // - Items can be either detached (prev = NULL), or attached to a list. - // 'value' points to something of interest. - // - List heads are always attached; if a list is empty, its head points - // to itself. 'count' contains the size of the list. - // If the list holds notes, 'pool' points back to the pool where it lives. - // Otherwise, that member is NULL. - struct AudioListItem *prev; - struct AudioListItem *next; - union { - void *value; // either Note* or SequenceChannelLayer* - s32 count; - } u; - struct NotePool *pool; -}; // size = 0x10 - -struct NotePool { - struct AudioListItem disabled; - struct AudioListItem decaying; - struct AudioListItem releasing; - struct AudioListItem active; -}; - -struct VibratoState { - /*0x00, 0x00*/ struct SequenceChannel *seqChannel; - /*0x04, 0x04*/ u32 time; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x08*/ s16 *curve; - /* , 0x0C*/ f32 extent; - /* , 0x10*/ f32 rate; - /* , 0x14*/ u8 active; -#else - /*0x08, */ s8 *curve; - /*0x0C, */ u8 active; - /*0x0E, */ u16 rate; - /*0x10, */ u16 extent; -#endif - /*0x12, 0x16*/ u16 rateChangeTimer; - /*0x14, 0x18*/ u16 extentChangeTimer; - /*0x16, 0x1A*/ u16 delay; -}; // size = 0x18, 0x1C on EU - -// Pitch sliding by up to one octave in the positive direction. Negative -// direction is "supported" by setting extent to be negative. The code -// extrapolates exponentially in the wrong direction in that case, but that -// doesn't prevent seqplayer from doing it, AFAICT. -struct Portamento { - u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 - f32 cur; - f32 speed; - f32 extent; -}; // size = 0x10 - -struct AdsrEnvelope { - s16 delay; - s16 arg; -}; // size = 0x4 - -struct AdpcmLoop { - u32 start; - u32 end; - u32 count; - u32 pad; - s16 state[16]; // only exists if count != 0. 8-byte aligned -}; - -struct AdpcmBook { - s32 order; - s32 npredictors; - s16 book[1]; // size 8 * order * npredictors. 8-byte aligned -}; - -struct AudioBankSample { -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x00 */ u32 codec : 4; - /* 0x00 */ u32 medium : 2; - /* 0x00 */ u32 bit1 : 1; - /* 0x00 */ u32 isPatched : 1; - /* 0x01 */ u32 size : 24; -#else - u8 unused; - u8 loaded; -#endif - u8 *sampleAddr; - struct AdpcmLoop *loop; - struct AdpcmBook *book; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - u32 sampleSize; // never read. either 0 or 1 mod 9, depending on padding -#endif -}; - -struct AudioBankSound { - struct AudioBankSample *sample; - f32 tuning; // frequency scale factor -}; // size = 0x8 - -struct Instrument { - /*0x00*/ u8 loaded; - /*0x01*/ u8 normalRangeLo; - /*0x02*/ u8 normalRangeHi; - /*0x03*/ u8 releaseRate; - /*0x04*/ struct AdsrEnvelope *envelope; - /*0x08*/ struct AudioBankSound lowNotesSound; - /*0x10*/ struct AudioBankSound normalNotesSound; - /*0x18*/ struct AudioBankSound highNotesSound; -}; // size = 0x20 - -struct Drum { - u8 releaseRate; - u8 pan; - u8 loaded; - struct AudioBankSound sound; - struct AdsrEnvelope *envelope; -}; - -struct AudioBank { - struct Drum **drums; - struct Instrument *instruments[1]; -}; // dynamic size - -struct CtlEntry { -#if !defined(VERSION_SH) && !defined(VERSION_CN) - u8 unused; -#endif - u8 numInstruments; - u8 numDrums; -#if defined(VERSION_SH) || defined(VERSION_CN) - u8 bankId1; - u8 bankId2; -#endif - struct Instrument **instruments; - struct Drum **drums; -}; // size = 0xC - -struct M64ScriptState { - u8 *pc; - u8 *stack[4]; - u8 remLoopIters[4]; - u8 depth; -}; // size = 0x1C - -// Also known as a Group, according to debug strings. -struct SequencePlayer { - /*US/JP, EU, SH */ -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /*0x000, 0x000, 0x000*/ u8 enabled : 1; -#else - /*0x000, 0x000*/ volatile u8 enabled : 1; -#endif - /*0x000, 0x000*/ u8 finished : 1; // never read - /*0x000, 0x000*/ u8 muted : 1; - /*0x000, 0x000*/ u8 seqDmaInProgress : 1; - /*0x000, 0x000*/ u8 bankDmaInProgress : 1; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* 0x000*/ u8 recalculateVolume : 1; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x000*/ u8 unkSh: 1; -#endif -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x001 */ s8 seqVariation; -#endif - /*0x002, 0x001, 0x001*/ u8 state; - /*0x003, 0x002*/ u8 noteAllocPolicy; - /*0x004, 0x003*/ u8 muteBehavior; - /*0x005, 0x004*/ u8 seqId; - /*0x006, 0x005*/ u8 defaultBank[1]; // must be an array to get a comparison - // to match; other u8's might also be part of that array - /*0x007, 0x006*/ u8 loadingBankId; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x008, ?????*/ u8 loadingBankNumInstruments; - /*0x009, ?????*/ u8 loadingBankNumDrums; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x007, 0x007*/ s8 seqVariationEu[1]; -#endif - /*0x00A, 0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU - /*0x00C, 0x00A*/ u16 tempoAcc; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x00E, 0x010*/ u16 fadeRemainingFrames; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x00C*/ s16 tempoAdd; -#endif - /*0x010, 0x00C, 0x00E*/ s16 transposition; - /*0x012, 0x00E, 0x010*/ u16 delay; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /*0x00E, 0x010, 0x012*/ u16 fadeRemainingFrames; - /* , 0x012, 0x014*/ u16 fadeTimerUnkEu; -#endif - /*0x014, 0x014*/ u8 *seqData; // buffer of some sort - /*0x018, 0x018, 0x1C*/ f32 fadeVolume; // set to 1.0f - /*0x01C, 0x01C*/ f32 fadeVelocity; // set to 0.0f - /*0x020, 0x020, 0x024*/ f32 volume; // set to 0.0f - /*0x024, 0x024*/ f32 muteVolumeScale; // set to 0.5f -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x028, 0x02C*/ f32 fadeVolumeScale; - /* , 0x02C*/ f32 appliedFadeVolume; -#else - /* */ u8 pad2[4]; -#endif - /*0x02C, 0x030, 0x034*/ struct SequenceChannel *channels[CHANNELS_MAX]; - /*0x06C, 0x070*/ struct M64ScriptState scriptState; - /*0x088, 0x08C*/ u8 *shortNoteVelocityTable; - /*0x08C, 0x090*/ u8 *shortNoteDurationTable; - /*0x090, 0x094*/ struct NotePool notePool; - /*0x0D0, 0x0D4*/ OSMesgQueue seqDmaMesgQueue; - /*0x0E8, 0x0EC*/ OSMesg seqDmaMesg; - /*0x0EC, 0x0F0*/ OSIoMesg seqDmaIoMesg; - /*0x100, 0x108*/ OSMesgQueue bankDmaMesgQueue; - /*0x118, 0x120*/ OSMesg bankDmaMesg; - /*0x11C, 0x124*/ OSIoMesg bankDmaIoMesg; - /*0x130, 0x13C*/ u8 *bankDmaCurrMemAddr; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x134, ?????*/ struct AudioBank *loadingBank; -#endif - /*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr; - /*0x13C, 0x144*/ ssize_t bankDmaRemaining; -}; // size = 0x140, 0x148 on EU, 0x14C on SH - -struct AdsrSettings { - u8 releaseRate; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - u8 sustain; -#else - u16 sustain; // sustain level, 2^16 = max -#endif - struct AdsrEnvelope *envelope; -}; // size = 0x8 - -struct AdsrState { - /*0x00, 0x00*/ u8 action; - /*0x01, 0x01*/ u8 state; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x02, */ s16 initial; // always 0 - /*0x04, */ s16 target; - /*0x06, */ s16 current; -#endif - /*0x08, 0x02*/ s16 envIndex; - /*0x0A, 0x04*/ s16 delay; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x08*/ f32 sustain; - /* , 0x0C*/ f32 velocity; - /* , 0x10*/ f32 fadeOutVel; - /* , 0x14*/ f32 current; - /* , 0x18*/ f32 target; - s32 pad1C; -#else - /*0x0C, */ s16 sustain; - /*0x0E, */ s16 fadeOutVel; - /*0x10, */ s32 velocity; - /*0x14, */ s32 currentHiRes; - /*0x18, */ s16 *volOut; -#endif - /*0x1C, 0x20*/ struct AdsrEnvelope *envelope; -}; // size = 0x20, 0x24 in EU - -struct ReverbBitsData { - /* 0x00 */ u8 bit0 : 1; - /* 0x00 */ u8 bit1 : 1; - /* 0x00 */ u8 bit2 : 1; - /* 0x00 */ u8 usesHeadsetPanEffects : 1; - /* 0x00 */ u8 stereoHeadsetEffects : 2; - /* 0x00 */ u8 strongRight : 1; - /* 0x00 */ u8 strongLeft : 1; -}; - -union ReverbBits { - /* 0x00 */ struct ReverbBitsData s; - /* 0x00 */ u8 asByte; -}; -struct ReverbInfo { - u8 reverbVol; - u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 - u8 pan; - union ReverbBits reverbBits; - f32 freqScale; - f32 velocity; - s32 unused; - s16 *filter; -}; - -struct NoteAttributes { - u8 reverbVol; -#if defined(VERSION_SH) || defined(VERSION_CN) - u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - u8 pan; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) - union ReverbBits reverbBits; -#endif - f32 freqScale; - f32 velocity; -#if defined(VERSION_JP) || defined(VERSION_US) - f32 pan; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) - s16 *filter; -#endif -}; // size = 0x10 - -// Also known as a SubTrack, according to debug strings. -// Confusingly, a SubTrack is a container of Tracks. -struct SequenceChannel { - /* U/J, EU, SH */ - /*0x00, 0x00*/ u8 enabled : 1; - /*0x00, 0x00*/ u8 finished : 1; - /*0x00, 0x00*/ u8 stopScript : 1; - /*0x00, 0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething - /*0x00, 0x00*/ u8 hasInstrument : 1; - /*0x00, 0x00*/ u8 stereoHeadsetEffects : 1; - /*0x00, ????*/ u8 largeNotes : 1; // notes specify duration and velocity - /*0x00, ????*/ u8 unused : 1; // never read, set to 0 -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x01*/ union { - struct { - u8 freqScale : 1; - u8 volume : 1; - u8 pan : 1; - } as_bitfields; - u8 as_u8; - } changes; -#endif - /*0x01, 0x02*/ u8 noteAllocPolicy; - /*0x02, 0x03, 0x03*/ u8 muteBehavior; - /*0x03, 0x04, 0x04*/ u8 reverbVol; // until EU: Q1.7, after EU: UQ0.8 - /*0x04, ????*/ u8 notePriority; // 0-3 -#if defined(VERSION_SH) || defined(VERSION_CN) - u8 unkSH06; // some priority -#endif - /*0x05, 0x06*/ u8 bankId; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x07*/ u8 reverbIndex; - /* , 0x08, 0x09*/ u8 bookOffset; - /* , 0x09*/ u8 newPan; - /* , 0x0A*/ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128) -#else - /*0x06, */ u8 updatesPerFrameUnused; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x0C*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 -#endif - /*0x08, 0x0C, 0x0E*/ u16 vibratoRateStart; // initially 0x800 - /*0x0A, 0x0E, 0x10*/ u16 vibratoExtentStart; - /*0x0C, 0x10, 0x12*/ u16 vibratoRateTarget; // initially 0x800 - /*0x0E, 0x12, 0x14*/ u16 vibratoExtentTarget; - /*0x10, 0x14, 0x16*/ u16 vibratoRateChangeDelay; - /*0x12, 0x16, 0x18*/ u16 vibratoExtentChangeDelay; - /*0x14, 0x18, 0x1A*/ u16 vibratoDelay; - /*0x16, 0x1A, 0x1C*/ u16 delay; - /*0x18, 0x1C, 0x1E*/ s16 instOrWave; // either 0 (none), instrument index + 1, or - // 0x80..0x83 for sawtooth/triangle/sine/square waves. - /*0x1A, 0x1E, 0x20*/ s16 transposition; - /*0x1C, 0x20, 0x24*/ f32 volumeScale; - /*0x20, 0x24, 0x28*/ f32 volume; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x24, */ f32 pan; - /*0x28, */ f32 panChannelWeight; // proportion of pan that comes from the channel (0..1) -#else - /* , 0x28*/ s32 pan; - /* , 0x2C*/ f32 appliedVolume; -#endif - /*0x2C, 0x30*/ f32 freqScale; - /*0x30, 0x34*/ u8 (*dynTable)[][2]; - /*0x34, ????*/ struct Note *noteUnused; // never read - /*0x38, ????*/ struct SequenceChannelLayer *layerUnused; // never read - /*0x3C, 0x40*/ struct Instrument *instrument; - /*0x40, 0x44*/ struct SequencePlayer *seqPlayer; - /*0x44, 0x48*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - /*0x54, 0x58 */ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, - // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment -#endif - /*0x5C, 0x60*/ struct M64ScriptState scriptState; - /*0x78, 0x7C*/ struct AdsrSettings adsr; - /*0x80, 0x84*/ struct NotePool notePool; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0xC0*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, - // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment - /* 0xC8*/ u16 unkC8; - /* 0xCC*/ s16 *filter; -#endif -}; // size = 0xC0, 0xC4 in EU, 0xD0 in SH - -// Also known as a Track, according to debug strings. -struct SequenceChannelLayer { - /* U/J, EU, SH */ - /*0x00, 0x00*/ u8 enabled : 1; - /*0x00, 0x00*/ u8 finished : 1; - /*0x00, 0x00*/ u8 stopSomething : 1; // ? - /*0x00, 0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x00*/ u8 unusedEu0b8 : 1; - /* , 0x00*/ u8 notePropertiesNeedInit : 1; - /* , 0x00*/ u8 ignoreDrumPan : 1; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* , , 0x01 */ union ReverbBits reverbBits; -#endif - /* , 0x01, 0x02*/ u8 instOrWave; -#endif - /*0x01, 0x02, 0x03*/ u8 status; // 0x03 in SH - /*0x02, 0x03*/ u8 noteDuration; // set to 0x80 - /*0x03, 0x04*/ u8 portamentoTargetNote; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - /* , 0x05*/ u8 pan; // 0..128 - /* , 0x06, 0x07*/ u8 notePan; -#endif - /*0x04, 0x08*/ struct Portamento portamento; - /*0x14, 0x18*/ struct AdsrSettings adsr; - /*0x1C, 0x20*/ u16 portamentoTime; - /*0x1E, 0x22*/ s16 transposition; // #semitones added to play commands - // (m64 instruction encoding only allows referring to the limited range - // 0..0x3f; this makes 0x40..0x7f accessible as well) - /*0x20, 0x24, 0x24*/ f32 freqScale; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x28*/ f32 freqScaleMultiplier; -#endif - /*0x24, 0x28, 0x2C*/ f32 velocitySquare; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x28, */ f32 pan; // 0..1 -#endif - /*0x2C, 0x2C, 0x30*/ f32 noteVelocity; -#if defined(VERSION_JP) || defined(VERSION_US) - /*0x30*/ f32 notePan; -#endif - /*0x34, 0x30, 0x34*/ f32 noteFreqScale; - /*0x38, 0x34*/ s16 shortNoteDefaultPlayPercentage; - /*0x3A, 0x36*/ s16 playPercentage; // it's not really a percentage... - /*0x3C, 0x38*/ s16 delay; - /*0x3E, 0x3A*/ s16 duration; - /*0x40, 0x3C*/ s16 delayUnused; // set to 'delay', never read - /*0x44, 0x40, 0x44*/ struct Note *note; - /*0x48, 0x44*/ struct Instrument *instrument; - /*0x4C, 0x48*/ struct AudioBankSound *sound; - /*0x50, 0x4C, 0x50*/ struct SequenceChannel *seqChannel; - /*0x54, 0x50*/ struct M64ScriptState scriptState; - /*0x70, 0x6C*/ struct AudioListItem listItem; -#if defined(VERSION_EU) - u8 pad2[4]; -#endif -}; // size = 0x80 - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -struct NoteSynthesisState { - /*0x00*/ u8 restart; - /*0x01*/ u8 sampleDmaIndex; - /*0x02*/ u8 prevHeadsetPanRight; - /*0x03*/ u8 prevHeadsetPanLeft; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x04*/ u8 reverbVol; - /* 0x05*/ u8 unk5; -#endif - /*0x04, 0x06*/ u16 samplePosFrac; - /*0x08*/ s32 samplePosInt; - /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; - /*0x10*/ s16 curVolLeft; // UQ0.16 (EU Q1.15) - /*0x12*/ s16 curVolRight; // UQ0.16 (EU Q1.15) -}; -struct NotePlaybackState { - /* U/J, EU, SH */ - /*0x04, 0x00, 0x00*/ u8 priority; - /* 0x01, 0x01*/ u8 waveId; - /* 0x02, 0x02*/ u8 sampleCountIndex; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x03*/ u8 bankId; - /* 0x04*/ u8 unkSH34; -#endif - /*0x08, 0x04, 0x06*/ s16 adsrVolScale; - /*0x18, 0x08, 0x08*/ f32 portamentoFreqScale; - /*0x1C, 0x0C, 0x0C*/ f32 vibratoFreqScale; - /*0x28, 0x10, */ struct SequenceChannelLayer *prevParentLayer; - /*0x2C, 0x14, 0x14*/ struct SequenceChannelLayer *parentLayer; - /*0x30, 0x18, 0x18*/ struct SequenceChannelLayer *wantedParentLayer; - /* , 0x1C, 0x1C*/ struct NoteAttributes attributes; - /*0x54, 0x28, 0x2C*/ struct AdsrState adsr; - /*0x74, 0x4C, */ struct Portamento portamento; - /*0x84, 0x5C, */ struct VibratoState vibratoState; -}; -struct NoteSubEu { - /*0x00*/ volatile u8 enabled : 1; - /*0x00*/ u8 needsInit : 1; - /*0x00*/ u8 finished : 1; - /*0x00*/ u8 envMixerNeedsInit : 1; - /*0x00*/ u8 stereoStrongRight : 1; - /*0x00*/ u8 stereoStrongLeft : 1; - /*0x00*/ u8 stereoHeadsetEffects : 1; - /*0x00*/ u8 usesHeadsetPanEffects : 1; - /*0x01*/ u8 reverbIndex : 3; - /*0x01*/ u8 bookOffset : 3; - /*0x01*/ u8 isSyntheticWave : 1; - /*0x01*/ u8 hasTwoAdpcmParts : 1; -#ifdef VERSION_EU - /*0x02*/ u8 bankId; -#else - /*0x02*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 -#endif - /*0x03*/ u8 headsetPanRight; - /*0x04*/ u8 headsetPanLeft; - /*0x05*/ u8 reverbVol; // UQ0.7 (EU Q1.7) - /*0x06*/ u16 targetVolLeft; // UQ0.12 (EU UQ0.10) - /*0x08*/ u16 targetVolRight; // UQ0.12 (EU UQ0.10) - /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 - /*0x0C*/ union { - s16 *samples; - struct AudioBankSound *audioBankSound; - } sound; -#if defined(VERSION_SH) || defined(VERSION_CN) - /*0x10*/ s16 *filter; -#endif -}; -struct Note { - /* U/J, EU, SH */ - /*0xA4, 0x00, 0x00*/ struct AudioListItem listItem; - /* 0x10, 0x10*/ struct NoteSynthesisState synthesisState; - // The next members are actually part of a struct (NotePlaybackState), but - // that results in messy US/EU ifdefs. Instead we cast to a struct pointer - // when needed... This breaks alignment on non-N64 platforms, which we hack - // around by skipping the padding in that case. - // TODO: use macros or something instead. -#ifdef TARGET_N64 - u8 pad0[12]; -#endif - - /*0x04, 0x30, 0x30*/ u8 priority; - /* 0x31, 0x31*/ u8 waveId; - /* 0x32, 0x32*/ u8 sampleCountIndex; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x33*/ u8 bankId; - /* 0x34*/ u8 unkSH34; -#endif - /*0x08, 0x34, 0x36*/ s16 adsrVolScale; - /*0x18, 0x38, */ f32 portamentoFreqScale; - /*0x1C, 0x3C, */ f32 vibratoFreqScale; - /*0x28, 0x40, */ struct SequenceChannelLayer *prevParentLayer; - /*0x2C, 0x44, 0x44*/ struct SequenceChannelLayer *parentLayer; - /*0x30, 0x48, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; - /* , 0x4C, 0x4C*/ struct NoteAttributes attributes; - /*0x54, 0x58, 0x5C*/ struct AdsrState adsr; - /*0x74, 0x7C*/ struct Portamento portamento; - /*0x84, 0x8C*/ struct VibratoState vibratoState; - u8 pad3[8]; - /* , 0xB0, 0xB4*/ struct NoteSubEu noteSubEu; -}; // size = 0xC0, known to be 0xC8 on SH -#else -// volatile Note, needed in synthesis_process_notes -struct vNote { - /* U/J, EU */ - /*0x00*/ volatile u8 enabled : 1; - long long int force_structure_alignment; -}; // size = 0xC0 -struct Note { - /* U/J, EU */ - /*0x00*/ u8 enabled : 1; - /*0x00*/ u8 needsInit : 1; - /*0x00*/ u8 restart : 1; - /*0x00*/ u8 finished : 1; - /*0x00*/ u8 envMixerNeedsInit : 1; - /*0x00*/ u8 stereoStrongRight : 1; - /*0x00*/ u8 stereoStrongLeft : 1; - /*0x00*/ u8 stereoHeadsetEffects : 1; - /*0x01*/ u8 usesHeadsetPanEffects; - /*0x02*/ u8 unk2; - /*0x03*/ u8 sampleDmaIndex; - /*0x04, 0x30*/ u8 priority; - /*0x05*/ u8 sampleCount; // 0, 8, 16, 32 or 64 - /*0x06*/ u8 instOrWave; - /*0x07*/ u8 bankId; // in NoteSubEu on EU - /*0x08*/ s16 adsrVolScale; - /* */ u8 pad1[2]; - /*0x0C, 0xB3*/ u16 headsetPanRight; - /*0x0E, 0xB4*/ u16 headsetPanLeft; - /*0x10*/ u16 prevHeadsetPanRight; - /*0x12*/ u16 prevHeadsetPanLeft; - /*0x14*/ s32 samplePosInt; - /*0x18, 0x38*/ f32 portamentoFreqScale; - /*0x1C, 0x3C*/ f32 vibratoFreqScale; - /*0x20*/ u16 samplePosFrac; - /*0x24*/ struct AudioBankSound *sound; - /*0x28, 0x40*/ struct SequenceChannelLayer *prevParentLayer; - /*0x2C, 0x44*/ struct SequenceChannelLayer *parentLayer; - /*0x30, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; - /*0x34*/ struct NoteSynthesisBuffers *synthesisBuffers; - /*0x38*/ f32 frequency; - /*0x3C*/ u16 targetVolLeft; // Q1.15, but will always be non-negative - /*0x3E*/ u16 targetVolRight; // Q1.15, but will always be non-negative - /*0x40*/ u8 reverbVol; // Q1.7 - /*0x41*/ u8 unused1; // never read, set to 0x3f - /*0x44*/ struct NoteAttributes attributes; - /*0x54, 0x58*/ struct AdsrState adsr; - /*0x74, 0x7C*/ struct Portamento portamento; - /*0x84, 0x8C*/ struct VibratoState vibratoState; - /*0x9C*/ s16 curVolLeft; // Q1.15, but will always be non-negative - /*0x9E*/ s16 curVolRight; // Q1.15, but will always be non-negative - /*0xA0*/ s16 reverbVolShifted; // Q1.15 - /*0xA2*/ s16 unused2; // never read, set to 0 - /*0xA4, 0x00*/ struct AudioListItem listItem; - /* */ u8 pad2[0xc]; -}; // size = 0xC0 -#endif - -struct NoteSynthesisBuffers { - s16 adpcmdecState[0x10]; - s16 finalResampleState[0x10]; -#if defined(VERSION_SH) || defined(VERSION_CN) - s16 unk[0x10]; - s16 filterBuffer[0x20]; - s16 panSamplesBuffer[0x20]; -#else - s16 mixEnvelopeState[0x28]; - s16 panResampleState[0x10]; - s16 panSamplesBuffer[0x20]; - s16 dummyResampleState[0x10]; -#if defined(VERSION_JP) || defined(VERSION_US) - s16 samples[0x40]; -#endif -#endif -}; - -#ifdef VERSION_EU -struct ReverbSettingsEU { - u8 downsampleRate; - u8 windowSize; // To be multiplied by 64 - u16 gain; -}; -#else -struct ReverbSettingsEU { - u8 downsampleRate; // always 1 - u8 windowSize; // To be multiplied by 16 - u16 gain; - u16 unk4; // always zero - u16 unk6; // always zero - s8 unk8; // always -1 - u16 unkA; // always 0x3000 - s16 unkC; // always zero - s16 unkE; // always zero -}; -#endif - -struct AudioSessionSettingsEU { - /* 0x00 */ u32 frequency; - /* 0x04 */ u8 unk1; // always 1 - /* 0x05 */ u8 maxSimultaneousNotes; - /* 0x06 */ u8 numReverbs; // always 1 - /* 0x07 */ u8 unk2; // always 0 - /* 0x08 */ struct ReverbSettingsEU *reverbSettings; - /* 0x0C */ u16 volume; - /* 0x0E */ u16 unk3; // always 0 - /* 0x10 */ u32 persistentSeqMem; - /* 0x14 */ u32 persistentBankMem; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x18 */ u32 unk18; // always 0 -#endif - /* 0x18, 0x1C */ u32 temporarySeqMem; - /* 0x1C, 0x20 */ u32 temporaryBankMem; -#if defined(VERSION_SH) || defined(VERSION_CN) - /* 0x24 */ u32 unk24; // always 0 - /* 0x28 */ u32 unkMem28; // always 0 - /* 0x2C */ u32 unkMem2C; // always 0 -#endif -}; // 0x30 on shindou - -struct AudioSessionSettings { - /*0x00*/ u32 frequency; - /*0x04*/ u8 maxSimultaneousNotes; - /*0x05*/ u8 reverbDownsampleRate; // always 1 - /*0x06*/ u16 reverbWindowSize; - /*0x08*/ u16 reverbGain; - /*0x0A*/ u16 volume; - /*0x0C*/ u32 persistentSeqMem; - /*0x10*/ u32 persistentBankMem; - /*0x14*/ u32 temporarySeqMem; - /*0x18*/ u32 temporaryBankMem; -}; // size = 0x1C - -struct AudioBufferParametersEU { - /*0x00*/ s16 presetUnk4; // audio frames per vsync? - /*0x02*/ u16 frequency; - /*0x04*/ u16 aiFrequency; // ?16 - /*0x06*/ s16 samplesPerFrameTarget; - /*0x08*/ s16 maxAiBufferLength; - /*0x0A*/ s16 minAiBufferLength; - /*0x0C*/ s16 updatesPerFrame; - /*0x0E*/ s16 samplesPerUpdate; - /*0x10*/ s16 samplesPerUpdateMax; - /*0x12*/ s16 samplesPerUpdateMin; - /*0x14*/ f32 resampleRate; // contains 32000.0f / frequency - /*0x18*/ f32 updatesPerFrameInv; // 1.0f / updatesPerFrame - /*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame) -}; - -struct EuAudioCmd { - union { -#if IS_BIG_ENDIAN - struct { - u8 op; - u8 arg1; - u8 arg2; - u8 arg3; - } s; -#else - struct { - u8 arg3; - u8 arg2; - u8 arg1; - u8 op; - } s; -#endif - s32 first; - } u; - union { - s32 as_s32; - u32 as_u32; - f32 as_f32; -#if IS_BIG_ENDIAN - u8 as_u8; - s8 as_s8; -#else - struct { - u8 pad0[3]; - u8 as_u8; - }; - struct { - u8 pad1[3]; - s8 as_s8; - }; -#endif - } u2; -}; - -#if defined(VERSION_SH) || defined(VERSION_CN) -struct PendingDmaSample { - u8 medium; - u8 bankId; - u8 idx; - uintptr_t devAddr; - void *vAddr; - u8 *resultSampleAddr; - s32 state; - s32 remaining; - s8 *io; - /*0x1C*/ struct AudioBankSample sample; - /*0x2C*/ OSMesgQueue queue; - /*0x44*/ OSMesg mesgs[1]; - /*0x48*/ OSIoMesg ioMesg; -}; - -struct UnkStruct80343D00 { - u32 someIndex; // array into one of the two slots below - struct PendingDmaSample arr[2]; -}; - -// in external.c -extern s32 D_SH_80343CF0; -extern struct UnkStruct80343D00 D_SH_80343D00; -#endif - -#endif // AUDIO_INTERNAL_H diff --git a/src/audio/audio_session_presets_sh.c b/src/audio/sh/audio_session_presets.c similarity index 97% rename from src/audio/audio_session_presets_sh.c rename to src/audio/sh/audio_session_presets.c index 6da66159..5b0614bf 100644 --- a/src/audio/audio_session_presets_sh.c +++ b/src/audio/sh/audio_session_presets.c @@ -1,8 +1,6 @@ #include "internal.h" #include "data.h" -#if defined(VERSION_SH) || defined(VERSION_CN) - struct ReverbSettingsEU sReverbSettings[] = { {0x01, 0x30, 0x2fff, 0x0000, 0x0000, -1, 0x3000, 0x0000, 0x0000}, {0x01, 0x28, 0x47ff, 0x0000, 0x0000, -1, 0x3000, 0x0000, 0x0000}, @@ -42,4 +40,3 @@ u16 D_SH_80315EF4 = 0; u16 D_SH_80315EF8 = 0; u16 D_SH_80315EFC = 0; -#endif diff --git a/src/audio/data.c b/src/audio/sh/data.c similarity index 54% rename from src/audio/data.c rename to src/audio/sh/data.c index f5217f08..997449b3 100644 --- a/src/audio/data.c +++ b/src/audio/sh/data.c @@ -3,40 +3,6 @@ #include "data.h" #include "effects.h" -extern struct OSMesgQueue OSMesgQueue0; -extern struct OSMesgQueue OSMesgQueue1; -extern struct OSMesgQueue OSMesgQueue2; -extern struct OSMesgQueue OSMesgQueue3; - -#ifdef VERSION_EU -struct ReverbSettingsEU sReverbSettings[] = { - { 0x04, 0x0c, 0x2fff }, - { 0x04, 0x0a, 0x47ff }, - { 0x04, 0x10, 0x2fff }, - { 0x04, 0x0e, 0x3fff }, - { 0x04, 0x0c, 0x4fff }, - { 0x04, 0x0a, 0x37ff } -}; -struct AudioSessionSettingsEU gAudioSessionPresets[] = { - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, - 0x00004400, 0x00002a00 }, - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, - 0x00004400, 0x00002a00 }, - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[2], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, - 0x00004400, 0x00002a00 }, - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[3], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, - 0x00004400, 0x00002a00 }, - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[4], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, - 0x00004400, 0x00002a00 }, - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00004000, 0x00006e00, - 0x00003f00, 0x00002a00 }, - { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00004100, 0x00006e00, - 0x00004400, 0x00002a80 }, - { 0x00007d00, 0x01, 0x14, 0x01, 0x00, &sReverbSettings[5], 0x7fff, 0x0000, 0x00003500, 0x00006280, - 0x00004000, 0x00001b00 } -}; -#endif - // Format: // - frequency // - max number of simultaneous notes @@ -48,145 +14,12 @@ struct AudioSessionSettingsEU gAudioSessionPresets[] = { // - memory used for persistent banks // - memory used for temporary sequences // - memory used for temporary banks -#if defined(VERSION_JP) || defined(VERSION_US) -struct AudioSessionSettings gAudioSessionPresets[18] = { -#ifdef VERSION_JP - { 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0E00, 0x3FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3E00, 0x6200, 0x3F00, 0x2A00 }, - { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3F00, 0x6200, 0x4400, 0x2A80 }, - { 32000, 20, 1, 0x0800, 0x37FF, 0x7FFF, 0x3300, 0x5500, 0x4000, 0x1B00 }, -#else - { 32000, 16, 1, 0x0C00, 0x2FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0E00, 0x3FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, - { 32000, 16, 1, 0x0C00, 0x2FFF, 0x7FFF, 0x4000, 0x6E00, 0x3F00, 0x2A00 }, - { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x4100, 0x6E00, 0x4400, 0x2A80 }, - { 32000, 20, 1, 0x0800, 0x37FF, 0x7FFF, 0x34C0, 0x6280, 0x4000, 0x1B00 }, -#endif - { 27000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 27000, 16, 1, 0x0800, 0x3FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 27000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 27000, 16, 1, 0x1000, 0x3FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 27000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 32000, 14, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 32000, 12, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 32000, 10, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 32000, 8, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -}; -#endif // gAudioCosineTable[k] = round((2**15 - 1) * cos(pi/2 * k / 127)). Unused. -#if defined(VERSION_JP) || defined(VERSION_US) -u16 gAudioCosineTable[128] = { - 0x7FFF, 32764, 32757, 32744, 32727, 32704, 32677, 32644, 32607, 32564, 32517, 32464, 32407, - 32344, 32277, 32205, 32127, 32045, 31958, 31866, 31770, 31668, 31561, 31450, 31334, 31213, - 31087, 30957, 30822, 30682, 30537, 30388, 30234, 30075, 29912, 29744, 29572, 29395, 29214, - 29028, 28838, 28643, 28444, 28241, 28033, 27821, 27605, 27385, 27160, 26931, 26698, 26461, - 26220, 25975, 25726, 25473, 25216, 24956, 24691, 24423, 24151, 23875, 23596, 23313, 23026, - 22736, 22442, 22145, 21845, 21541, 21234, 20924, 20610, 20294, 19974, 19651, 19325, 18997, - 18665, 18331, 17993, 17653, 17310, 16965, 16617, 16266, 15913, 15558, 15200, 14840, 14477, - 14113, 13746, 13377, 13006, 12633, 12258, 11881, 11503, 11122, 10740, 10357, 9971, 9584, - 9196, 8806, 8415, 8023, 7630, 7235, 6839, 6442, 6044, 5646, 5246, 4845, 4444, - 4042, 3640, 3237, 2833, 2429, 2025, 1620, 1216, 810, 405, 0, -}; -#endif // Transforms a pitch scale factor in -127..127 into a frequency scale factor // between -1 and +1 octave. // gPitchBendFrequencyScale[k] = 0.5 * 2^(k/127) -#if !defined(VERSION_SH) && !defined(VERSION_CN) -#if defined(VERSION_EU) -f32 gPitchBendFrequencyScale[256] = { - 0.5f, -#else -f32 gPitchBendFrequencyScale[255] = { -#endif - 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f, - 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, - 0.551614f, 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, - 0.579387f, 0.582558f, 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.601950f, 0.605245f, - 0.608557f, 0.611888f, 0.615236f, 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f, - 0.639196f, 0.642694f, 0.646212f, 0.649748f, 0.653304f, 0.656880f, 0.660475f, 0.664089f, 0.667724f, - 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, 0.689952f, 0.693727f, 0.697524f, 0.701341f, - 0.705180f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, 0.728655f, 0.732642f, 0.736652f, - 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.765340f, 0.769529f, 0.773740f, - 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f, 0.812696f, - 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.839750f, 0.844346f, 0.848966f, 0.853613f, - 0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.896590f, - 0.901496f, 0.906430f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.941730f, - 0.946884f, 0.952066f, 0.957277f, 0.962516f, 0.967783f, 0.973080f, 0.978405f, 0.983760f, 0.989144f, - 0.994557f, 1.0f, 1.005473f, 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f, - 1.044630f, 1.050347f, 1.056095f, 1.061875f, 1.067687f, 1.073530f, 1.079405f, 1.085312f, 1.091252f, - 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, 1.127579f, 1.133750f, 1.139955f, 1.146193f, - 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, 1.190831f, 1.197348f, 1.203901f, - 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, 1.257631f, 1.264514f, - 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f, 1.328178f, - 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f, - 1.402683f, 1.410360f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f, - 1.473304f, 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f, - 1.547481f, 1.555950f, 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f, - 1.625392f, 1.634287f, 1.643231f, 1.652224f, 1.661266f, 1.670358f, 1.679500f, 1.688691f, 1.697933f, - 1.707225f, 1.716569f, 1.725963f, 1.735409f, 1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f, - 1.793179f, 1.802993f, 1.812860f, 1.822782f, 1.832757f, 1.842788f, 1.852873f, 1.863013f, 1.873209f, - 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, 1.946159f, 1.956810f, 1.967520f, - 1.978287f, 1.989114f, 2.0f -}; -// Frequencies for notes using the standard twelve-tone equal temperament scale. -// For indices 0..116, gNoteFrequencies[k] = 2^((k-39)/12). -// For indices 117..128, gNoteFrequencies[k] = 0.5 * 2^((k-39)/12). -// The 39 in the formula refers to piano key 40 (middle C, at 256 Hz) being -// the reference frequency, which is assigned value 1. -// clang-format off -f32 gNoteFrequencies[128] = { - 0.105112f, 0.111362f, 0.117984f, 0.125f, 0.132433f, 0.140308f, 0.148651f, 0.15749f, 0.166855f, 0.176777f, 0.187288f, 0.198425f, - 0.210224f, 0.222725f, 0.235969f, 0.25f, 0.264866f, 0.280616f, 0.297302f, 0.31498f, 0.33371f, 0.353553f, 0.374577f, 0.39685f, - 0.420448f, 0.445449f, 0.471937f, 0.5f, 0.529732f, 0.561231f, 0.594604f, 0.629961f, 0.66742f, 0.707107f, 0.749154f, 0.793701f, - 0.840897f, 0.890899f, 0.943875f, 1.0f, 1.059463f, 1.122462f, 1.189207f, 1.259921f, 1.33484f, 1.414214f, 1.498307f, 1.587401f, - 1.681793f, 1.781798f, 1.887749f, 2.0f, 2.118926f, 2.244924f, 2.378414f, 2.519842f, 2.66968f, 2.828428f, 2.996615f, 3.174803f, - 3.363586f, 3.563596f, 3.775498f, 4.0f, 4.237853f, 4.489849f, 4.756829f, 5.039685f, 5.33936f, 5.656855f, 5.993229f, 6.349606f, - 6.727173f, 7.127192f, 7.550996f, 8.0f, 8.475705f, 8.979697f, 9.513658f, 10.07937f, 10.67872f, 11.31371f, 11.986459f, 12.699211f, - 13.454346f, 14.254383f, 15.101993f, 16.0f, 16.95141f, 17.959394f, 19.027315f, 20.15874f, 21.35744f, 22.62742f, 23.972918f, 25.398422f, - 26.908691f, 28.508766f, 30.203985f, 32.0f, 33.90282f, 35.91879f, 38.05463f, 40.31748f, 42.71488f, 45.25484f, 47.945835f, 50.796844f, - 53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f, 85.42976f, 45.25484f, 47.945835f, 50.796844f, - 53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f -}; -// clang-format on - -// goes up by ~12 at each step for the first 4 values (starting from 0), then by ~6 -u8 gDefaultShortNoteVelocityTable[16] = { - 12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127, -}; - -// goes down by 26 at each step for the first 4 values (starting from 255), then by ~12 -u8 gDefaultShortNoteDurationTable[16] = { - 229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0, -}; - -#if defined(VERSION_JP) || defined(VERSION_US) -// gVibratoCurve[k] = k*8 -s8 gVibratoCurve[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; -#endif - -struct AdsrEnvelope gDefaultEnvelope[] = { - { BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms - { BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds - { BSWAP16(ADSR_HANG), 0 } // then continue staying there -}; -#endif - -#ifdef VERSION_EU -struct NoteSubEu gZeroNoteSub = { 0 }; -struct NoteSubEu gDefaultNoteSub = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL } }; -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s16 sSawtoothWaves[256] = { 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, 11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503, @@ -339,47 +172,6 @@ s16 gEuUnknownWave7[256] = { }; s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 }; -#else -// !VERSION_EU - -s16 sSineWave[0x40] = { - 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244, - 28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897, - 27244, 25329, 23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211, 0, - -3211, -6392, -9511, -12539, -15446, -18204, -20787, -23169, -25329, -27244, -28897, - -30272, -31356, -32137, -32609, -0x7FFF, -32609, -32137, -31356, -30272, -28897, -27244, - -25329, -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, -}; - -s16 sSquareWave[0x40] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, - -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -}; -s16 sTriangleWave[0x40] = { - 0, 0x7FF, 0xFFF, 0x17FF, 0x1FFF, 0x27FF, 0x2FFF, 0x37FF, 0x3FFF, 0x47FF, 0x4FFF, - 0x57FF, 0x5FFF, 0x67FF, 0x6FFF, 0x77FF, 0x7FFF, 0x77FF, 0x6FFF, 0x67FF, 0x5FFF, 0x57FF, - 0x4FFF, 0x47FF, 0x3FFF, 0x37FF, 0x2FFF, 0x27FF, 0x1FFF, 0x17FF, 0xFFF, 0x7FF, 0, - -0x7FF, -0xFFF, -0x17FF, -0x1FFF, -10239, -0x2FFF, -0x37FF, -0x3FFF, -0x47FF, -0x4FFF, -22527, - -24575, -26623, -28671, -30719, -0x7FFF, -30719, -28671, -26623, -24575, -22527, -0x4FFF, - -0x47FF, -0x3FFF, -0x37FF, -0x2FFF, -0x27FF, -0x1FFF, -0x17FF, -0xFFF, -0x7FF, -}; - -s16 sSawtoothWave[0x40] = { - 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, - 11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503, - 22527, 23551, 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, -0x7FFF, - -31743, -30719, -29695, -28671, -27647, -26623, -25599, -24575, -23551, -22527, -21503, - -0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239, - -9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, -}; -s16 *gWaveSamples[4] = { sSawtoothWave, sTriangleWave, sSineWave, sSquareWave }; -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) s32 unk_sh_data_0[2] = {0, 0}; f32 gPitchBendFrequencyScale[256] = { 0.5f, 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, @@ -412,9 +204,7 @@ f32 gPitchBendFrequencyScale[256] = { 1.873209f, 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, 1.946159f, 1.956810f, 1.967520f, 1.978287f, 1.989114f, 2.0f }; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) f32 unk_sh_data_1[] = { 0.890899f, 0.890899f, 0.89171f, 0.892521f, 0.893333f, 0.894146f, 0.89496f, 0.895774f, 0.89659f, 0.897406f, 0.898222f, 0.89904f, 0.899858f, 0.900677f, 0.901496f, 0.902317f, @@ -486,9 +276,7 @@ u8 unk_sh_data2[4] = { 0, 0, 0, 0 }; struct NoteSubEu gZeroNoteSub = { 0 }; struct NoteSubEu gDefaultNoteSub = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { NULL }, -#if defined(VERSION_SH) || defined(VERSION_CN) 0 -#endif }; u16 gHeadsetPanQuantization[0x40] = { @@ -499,23 +287,11 @@ u16 gHeadsetPanQuantization[0x40] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#endif -#ifdef VERSION_EU -u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 }; -u16 gHeadsetPanQuantization[0x10] = { - 0x40, 0x40, 0x30, 0x30, 0x20, 0x20, 0x10, 0, 0, 0, -}; -#elif defined(VERSION_JP) || defined(VERSION_US) -u16 gHeadsetPanQuantization[10] = { 0x40, 0x30, 0x20, 0x10, 0, 0, 0, 0, 0, 0 }; -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s16 euUnknownData_80301950[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, }; -#endif // Linearly interpolated between // f(0/2 * 127) = 1 @@ -582,135 +358,6 @@ f32 gDefaultPanVolume[128] = { 0.012368f, 0.0f }; -#if defined(VERSION_JP) || defined(VERSION_US) -// gVolRampingLhs136[k] = 2^16 * max(1, (256*k)^(1/17) -f32 gVolRampingLhs136[128] = { - 65536.0f, 90811.555f, 94590.766f, 96873.96f, 98527.26f, 99829.06f, 100905.47f, - 101824.61f, 102627.57f, 103341.086f, 103983.55f, 104568.164f, 105104.75f, 105600.8f, - 106062.14f, 106493.46f, 106898.52f, 107280.414f, 107641.73f, 107984.62f, 108310.93f, - 108622.23f, 108919.875f, 109205.055f, 109478.8f, 109742.0f, 109995.48f, 110239.94f, - 110476.02f, 110704.305f, 110925.3f, 111139.45f, 111347.21f, 111548.945f, 111745.0f, - 111935.7f, 112121.35f, 112302.2f, 112478.51f, 112650.51f, 112818.4f, 112982.38f, - 113142.66f, 113299.37f, 113452.69f, 113602.766f, 113749.734f, 113893.73f, 114034.87f, - 114173.26f, 114309.02f, 114442.26f, 114573.055f, 114701.5f, 114827.69f, 114951.695f, - 115073.6f, 115193.47f, 115311.375f, 115427.39f, 115541.56f, 115653.96f, 115764.63f, - 115873.64f, 115981.04f, 116086.86f, 116191.164f, 116293.99f, 116395.38f, 116495.38f, - 116594.02f, 116691.34f, 116787.39f, 116882.19f, 116975.77f, 117068.17f, 117159.414f, - 117249.54f, 117338.57f, 117426.53f, 117513.45f, 117599.35f, 117684.266f, 117768.2f, - 117851.195f, 117933.266f, 118014.44f, 118094.72f, 118174.14f, 118252.71f, 118330.46f, - 118407.4f, 118483.55f, 118558.914f, 118633.53f, 118707.4f, 118780.54f, 118852.97f, - 118924.695f, 118995.74f, 119066.11f, 119135.82f, 119204.88f, 119273.31f, 119341.125f, - 119408.32f, 119474.92f, 119540.93f, 119606.36f, 119671.22f, 119735.52f, 119799.28f, - 119862.5f, 119925.195f, 119987.36f, 120049.02f, 120110.18f, 120170.84f, 120231.016f, - 120290.71f, 120349.945f, 120408.7f, 120467.016f, 120524.875f, 120582.3f, 120639.28f, - 120695.84f, 120751.984f -}; - -// gVolRampingRhs136[k] = 1 / max(1, (256*k)^(1/17)) -f32 gVolRampingRhs136[128] = { - 1.0f, 0.72167f, 0.692837f, 0.676508f, 0.665156f, 0.656482f, 0.649479f, 0.643616f, 0.638581f, - 0.634172f, 0.630254f, 0.62673f, 0.62353f, 0.620601f, 0.617902f, 0.615399f, 0.613067f, 0.610885f, - 0.608835f, 0.606901f, 0.605073f, 0.603339f, 0.60169f, 0.600119f, 0.598618f, 0.597183f, 0.595806f, - 0.594485f, 0.593215f, 0.591991f, 0.590812f, 0.589674f, 0.588573f, 0.587509f, 0.586478f, 0.585479f, - 0.58451f, 0.583568f, 0.582654f, 0.581764f, 0.580898f, 0.580055f, 0.579233f, 0.578432f, 0.57765f, - 0.576887f, 0.576142f, 0.575414f, 0.574701f, 0.574005f, 0.573323f, 0.572656f, 0.572002f, 0.571361f, - 0.570733f, 0.570118f, 0.569514f, 0.568921f, 0.568339f, 0.567768f, 0.567207f, 0.566656f, 0.566114f, - 0.565582f, 0.565058f, 0.564543f, 0.564036f, 0.563537f, 0.563046f, 0.562563f, 0.562087f, 0.561618f, - 0.561156f, 0.560701f, 0.560253f, 0.559811f, 0.559375f, 0.558945f, 0.558521f, 0.558102f, 0.557689f, - 0.557282f, 0.55688f, 0.556483f, 0.556091f, 0.555704f, 0.555322f, 0.554944f, 0.554571f, 0.554203f, - 0.553839f, 0.553479f, 0.553123f, 0.552772f, 0.552424f, 0.55208f, 0.55174f, 0.551404f, 0.551071f, - 0.550742f, 0.550417f, 0.550095f, 0.549776f, 0.549461f, 0.549148f, 0.548839f, 0.548534f, 0.548231f, - 0.547931f, 0.547634f, 0.54734f, 0.547048f, 0.54676f, 0.546474f, 0.546191f, 0.54591f, 0.545632f, - 0.545357f, 0.545084f, 0.544813f, 0.544545f, 0.54428f, 0.544016f, 0.543755f, 0.543496f, 0.543239f, - 0.542985f, 0.542732f -}; - -// gVolRampingLhs144[k] = 2^16 * max(1, (256*k)^(1/18)) -f32 gVolRampingLhs144[128] = { - 65536.0f, 89180.734f, 92681.9f, 94793.33f, 96320.52f, 97522.02f, 98514.84f, - 99362.14f, 100101.99f, 100759.16f, 101350.664f, 101888.74f, 102382.46f, 102838.75f, - 103263.016f, 103659.58f, 104031.914f, 104382.89f, 104714.88f, 105029.89f, 105329.61f, - 105615.5f, 105888.81f, 106150.63f, 106401.914f, 106643.49f, 106876.12f, 107100.44f, - 107317.05f, 107526.47f, 107729.17f, 107925.6f, 108116.125f, 108301.12f, 108480.88f, - 108655.72f, 108825.91f, 108991.68f, 109153.28f, 109310.914f, 109464.77f, 109615.04f, - 109761.88f, 109905.46f, 110045.92f, 110183.41f, 110318.02f, 110449.91f, 110579.17f, - 110705.914f, 110830.234f, 110952.234f, 111071.99f, 111189.59f, 111305.12f, 111418.64f, - 111530.23f, 111639.95f, 111747.875f, 111854.05f, 111958.54f, 112061.4f, 112162.67f, - 112262.42f, 112360.68f, 112457.51f, 112552.93f, 112647.0f, 112739.76f, 112831.23f, - 112921.46f, 113010.484f, 113098.33f, 113185.02f, 113270.61f, 113355.11f, 113438.555f, - 113520.97f, 113602.375f, 113682.805f, 113762.27f, 113840.81f, 113918.44f, 113995.18f, - 114071.055f, 114146.08f, 114220.266f, 114293.65f, 114366.24f, 114438.06f, 114509.12f, - 114579.44f, 114649.02f, 114717.91f, 114786.086f, 114853.586f, 114920.42f, 114986.6f, - 115052.14f, 115117.055f, 115181.34f, 115245.04f, 115308.13f, 115370.65f, 115432.59f, - 115493.98f, 115554.81f, 115615.11f, 115674.875f, 115734.12f, 115792.85f, 115851.08f, - 115908.82f, 115966.07f, 116022.85f, 116079.16f, 116135.01f, 116190.4f, 116245.35f, - 116299.87f, 116353.945f, 116407.6f, 116460.84f, 116513.67f, 116566.09f, 116618.125f, - 116669.76f, 116721.01f -}; - -// gVolRampingRhs144[k] = 1 / max(1, (256*k)^(1/18)) -f32 gVolRampingRhs144[128] = { - 1.0f, 0.734867f, 0.707107f, 0.691357f, 0.680395f, 0.672012f, 0.66524f, 0.659567f, 0.654692f, - 0.650422f, 0.646626f, 0.643211f, 0.64011f, 0.637269f, 0.634651f, 0.632223f, 0.629961f, 0.627842f, - 0.625852f, 0.623975f, 0.622199f, 0.620515f, 0.618913f, 0.617387f, 0.615929f, 0.614533f, 0.613196f, - 0.611912f, 0.610677f, 0.609487f, 0.60834f, 0.607233f, 0.606163f, 0.605128f, 0.604125f, 0.603153f, - 0.60221f, 0.601294f, 0.600403f, 0.599538f, 0.598695f, 0.597874f, 0.597074f, 0.596294f, 0.595533f, - 0.59479f, 0.594064f, 0.593355f, 0.592661f, 0.591983f, 0.591319f, 0.590669f, 0.590032f, 0.589408f, - 0.588796f, 0.588196f, 0.587608f, 0.58703f, 0.586463f, 0.585906f, 0.58536f, 0.584822f, 0.584294f, - 0.583775f, 0.583265f, 0.582762f, 0.582268f, 0.581782f, 0.581303f, 0.580832f, 0.580368f, 0.579911f, - 0.57946f, 0.579017f, 0.578579f, 0.578148f, 0.577722f, 0.577303f, 0.576889f, 0.576481f, 0.576078f, - 0.575681f, 0.575289f, 0.574902f, 0.574519f, 0.574142f, 0.573769f, 0.5734f, 0.573036f, 0.572677f, - 0.572321f, 0.57197f, 0.571623f, 0.57128f, 0.57094f, 0.570605f, 0.570273f, 0.569945f, 0.56962f, - 0.569299f, 0.568981f, 0.568667f, 0.568355f, 0.568047f, 0.567743f, 0.567441f, 0.567142f, 0.566846f, - 0.566553f, 0.566263f, 0.565976f, 0.565692f, 0.56541f, 0.565131f, 0.564854f, 0.56458f, 0.564309f, - 0.56404f, 0.563773f, 0.563509f, 0.563247f, 0.562987f, 0.56273f, 0.562475f, 0.562222f, 0.561971f, - 0.561722f, 0.561476f -}; - -// gVolRampingLhs128[k] = 2^16 * max(1, (256*k)^(1/16)) -f32 gVolRampingLhs128[128] = { - 65536.0f, 92681.9f, 96785.28f, 99269.31f, 101070.33f, 102489.78f, 103664.336f, - 104667.914f, 105545.09f, 106324.92f, 107027.39f, 107666.84f, 108253.95f, 108796.87f, - 109301.95f, 109774.29f, 110217.98f, 110636.39f, 111032.33f, 111408.164f, 111765.9f, - 112107.234f, 112433.66f, 112746.46f, 113046.766f, 113335.555f, 113613.72f, 113882.02f, - 114141.164f, 114391.77f, 114634.414f, 114869.58f, 115097.74f, 115319.31f, 115534.68f, - 115744.19f, 115948.16f, 116146.875f, 116340.625f, 116529.66f, 116714.195f, 116894.46f, - 117070.64f, 117242.945f, 117411.52f, 117576.55f, 117738.17f, 117896.54f, 118051.77f, - 118204.0f, 118353.35f, 118499.92f, 118643.83f, 118785.16f, 118924.01f, 119060.47f, - 119194.625f, 119326.555f, 119456.336f, 119584.03f, 119709.71f, 119833.445f, 119955.29f, - 120075.31f, 120193.555f, 120310.08f, 120424.94f, 120538.17f, 120649.836f, 120759.97f, - 120868.62f, 120975.82f, 121081.62f, 121186.05f, 121289.14f, 121390.94f, 121491.47f, - 121590.766f, 121688.87f, 121785.79f, 121881.57f, 121976.24f, 122069.82f, 122162.33f, - 122253.805f, 122344.266f, 122433.73f, 122522.23f, 122609.77f, 122696.4f, 122782.11f, - 122866.93f, 122950.89f, 123033.99f, 123116.26f, 123197.72f, 123278.37f, 123358.24f, - 123437.34f, 123515.69f, 123593.3f, 123670.19f, 123746.36f, 123821.84f, 123896.63f, - 123970.76f, 124044.23f, 124117.04f, 124189.23f, 124260.78f, 124331.73f, 124402.07f, - 124471.83f, 124540.99f, 124609.59f, 124677.63f, 124745.12f, 124812.055f, 124878.47f, - 124944.34f, 125009.71f, 125074.57f, 125138.92f, 125202.79f, 125266.164f, 125329.06f, - 125391.5f, 125453.47f -}; - -// gVolRampingRhs128[k] = 1 / max(1, (256*k)^(1/16)) -f32 gVolRampingRhs128[128] = { - 1.0f, 0.707107f, 0.677128f, 0.660184f, 0.64842f, 0.639439f, 0.632194f, 0.626133f, 0.620929f, - 0.616375f, 0.612329f, 0.608693f, 0.605391f, 0.60237f, 0.599587f, 0.597007f, 0.594604f, 0.592355f, - 0.590243f, 0.588251f, 0.586369f, 0.584583f, 0.582886f, 0.581269f, 0.579725f, 0.578247f, 0.576832f, - 0.575473f, 0.574166f, 0.572908f, 0.571696f, 0.570525f, 0.569394f, 0.5683f, 0.567241f, 0.566214f, - 0.565218f, 0.564251f, 0.563311f, 0.562398f, 0.561508f, 0.560642f, 0.559799f, 0.558976f, 0.558173f, - 0.55739f, 0.556625f, 0.555877f, 0.555146f, 0.554431f, 0.553732f, 0.553047f, 0.552376f, 0.551719f, - 0.551075f, 0.550443f, 0.549823f, 0.549216f, 0.548619f, 0.548033f, 0.547458f, 0.546892f, 0.546337f, - 0.545791f, 0.545254f, 0.544726f, 0.544206f, 0.543695f, 0.543192f, 0.542696f, 0.542209f, 0.541728f, - 0.541255f, 0.540788f, 0.540329f, 0.539876f, 0.539429f, 0.538988f, 0.538554f, 0.538125f, 0.537702f, - 0.537285f, 0.536873f, 0.536467f, 0.536065f, 0.535669f, 0.535277f, 0.534891f, 0.534509f, 0.534131f, - 0.533759f, 0.53339f, 0.533026f, 0.532666f, 0.53231f, 0.531958f, 0.53161f, 0.531266f, 0.530925f, - 0.530588f, 0.530255f, 0.529926f, 0.529599f, 0.529277f, 0.528957f, 0.528641f, 0.528328f, 0.528018f, - 0.527711f, 0.527407f, 0.527106f, 0.526808f, 0.526513f, 0.52622f, 0.525931f, 0.525644f, 0.525359f, - 0.525077f, 0.524798f, 0.524522f, 0.524247f, 0.523975f, 0.523706f, 0.523439f, 0.523174f, 0.522911f, - 0.522651f, 0.522393f -}; -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) u16 unk_sh_data_3[] = { // 30 entries // pattern: @@ -877,35 +524,12 @@ u16 unk_sh_data_4[] = { 0x5FFF, 0x9001, 0x7FFF, 0x8001 }; -#endif - -#if !defined(VERSION_SH) && !defined(VERSION_CN) -s16 gTatumsPerBeat = TATUMS_PER_BEAT; -s8 gUnusedCount80333EE8 = UNUSED_COUNT_80333EE8; -s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_HEAP_SIZE); -s32 gAudioInitPoolSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_INIT_POOL_SIZE); -volatile s32 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; -#endif - -#if defined(VERSION_EU) -u8 bufferDelete2[12] = { 0 }; -u8 D_EU_80302010 = 0; -u8 D_EU_80302014 = 0; - -struct OSMesgQueue *OSMesgQueues[4] = { &OSMesgQueue0, &OSMesgQueue1, &OSMesgQueue2, &OSMesgQueue3 }; -#elif defined(VERSION_JP) || defined(VERSION_US) -s8 sUnused8033EF8 = 24; -#endif // .bss volatile s32 gAudioFrameCount; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 gCurrAudioFrameDmaCount; -#else -volatile s32 gCurrAudioFrameDmaCount; -#endif s32 gAudioTaskIndex; s32 gCurrAiBufferIndex; @@ -916,46 +540,35 @@ u64 *gAudioCmd; struct SPTask *gAudioTask; struct SPTask gAudioTasks[2]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) f32 D_EU_802298D0; s32 gRefreshRate; -#endif s16 *gAiBuffers[NUMAIBUFFERS]; s16 gAiBufferLengths[NUMAIBUFFERS]; -#if defined(VERSION_JP) || defined(VERSION_US) -u32 gUnused80226E58[0x10]; -u16 gUnused80226E98[0x10]; -#endif - u32 gAudioRandom; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 gAudioErrorFlags; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) volatile u32 gAudioLoadLockSH; struct EuAudioCmd sAudioCmd[0x100]; u8 D_SH_80350F18; u8 D_SH_80350F19; -OSMesg D_SH_80350F1C[1]; -OSMesgQueue D_SH_80350F20; // address written to D_SH_80350F38 -OSMesgQueue *D_SH_80350F38; +OSMesg OSMesg0[1]; +OSMesgQueue OSMesgQueue0Data; +OSMesgQueue *OSMesgQueue0; -OSMesg D_SH_80350F40[4]; -OSMesgQueue D_SH_80350F50; // address written to D_SH_80350F68 -OSMesgQueue *D_SH_80350F68; +OSMesg OSMesg1[4]; +OSMesgQueue OSMesgQueue1Data; +OSMesgQueue *OSMesgQueue1; -OSMesg D_SH_80350F6C[1]; -OSMesgQueue D_SH_80350F70; // address written to D_SH_80350F88 -OSMesgQueue *D_SH_80350F88; +OSMesg OSMesg2[1]; +OSMesgQueue OSMesgQueue2Data; +OSMesgQueue *OSMesgQueue2; -OSMesg D_SH_80350F8C[1]; -OSMesgQueue D_SH_80350F90; // address written to D_SH_80350F90 -OSMesgQueue *D_SH_80350FA8; -#endif +OSMesg OSMesg3[1]; +OSMesgQueue OSMesgQueue3Data; +OSMesgQueue *OSMesgQueue3; u64 gAudioGlobalsEndMarker; diff --git a/src/audio/data.h b/src/audio/sh/data.h similarity index 56% rename from src/audio/data.h rename to src/audio/sh/data.h index 26672d19..a7830fa1 100644 --- a/src/audio/data.h +++ b/src/audio/sh/data.h @@ -13,18 +13,10 @@ #define NUMAIBUFFERS 3 // constant .data -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern struct AudioSessionSettingsEU gAudioSessionPresets[]; -#else -extern struct AudioSessionSettings gAudioSessionPresets[18]; -#endif extern u16 D_80332388[128]; // unused -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern f32 gPitchBendFrequencyScale[256]; -#else -extern f32 gPitchBendFrequencyScale[255]; -#endif extern f32 gNoteFrequencies[128]; extern u8 gDefaultShortNoteVelocityTable[16]; @@ -32,26 +24,14 @@ extern u8 gDefaultShortNoteDurationTable[16]; extern s8 gVibratoCurve[16]; extern struct AdsrEnvelope gDefaultEnvelope[3]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern s16 gEuUnknownWave7[256]; extern s16 *gWaveSamples[6]; -#else -extern s16 *gWaveSamples[4]; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern u8 euUnknownData_8030194c[4]; -#ifdef VERSION_EU -extern u16 gHeadsetPanQuantization[0x10]; -#else extern u16 gHeadsetPanQuantization[0x40]; -#endif extern s16 euUnknownData_80301950[64]; extern struct NoteSubEu gZeroNoteSub; extern struct NoteSubEu gDefaultNoteSub; -#else -extern u16 gHeadsetPanQuantization[10]; -#endif extern f32 gHeadsetPanVolume[128]; extern f32 gStereoPanVolume[128]; extern f32 gDefaultPanVolume[128]; @@ -74,11 +54,7 @@ extern volatile s32 gAudioLoadLock; extern volatile s32 gAudioFrameCount; // number of DMAs performed during this frame -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern s32 gCurrAudioFrameDmaCount; -#else -extern volatile s32 gCurrAudioFrameDmaCount; -#endif extern s32 gAudioTaskIndex; extern s32 gCurrAiBufferIndex; @@ -89,27 +65,19 @@ extern u64 *gAudioCmd; extern struct SPTask *gAudioTask; extern struct SPTask gAudioTasks[2]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern f32 D_EU_802298D0; extern s32 gRefreshRate; -#endif extern s16 *gAiBuffers[NUMAIBUFFERS]; extern s16 gAiBufferLengths[NUMAIBUFFERS]; -#if defined(VERSION_SH) || defined(VERSION_CN) #define AIBUFFER_LEN 0xb00 -#elif defined(VERSION_EU) -#define AIBUFFER_LEN (0xa0 * 17) -#else -#define AIBUFFER_LEN (0xa0 * 16) -#endif extern u32 gUnused80226E58[0x10]; extern u16 gUnused80226E98[0x10]; extern u32 gAudioRandom; +extern s32 gAudioErrorFlags; -#if defined(VERSION_SH) || defined(VERSION_CN) extern f32 unk_sh_data_1[]; extern volatile u32 gAudioLoadLockSH; @@ -117,38 +85,13 @@ extern volatile u32 gAudioLoadLockSH; extern u8 D_SH_80350F18; extern u8 D_SH_80350F19; -extern OSMesg D_SH_80350F1C[1]; -extern OSMesgQueue D_SH_80350F20; // address written to D_SH_80350F38 -extern OSMesgQueue *D_SH_80350F38; - -extern OSMesg D_SH_80350F40[4]; -extern OSMesgQueue D_SH_80350F50; // address written to D_SH_80350F68 -extern OSMesgQueue *D_SH_80350F68; - -extern OSMesg D_SH_80350F6C[1]; -extern OSMesgQueue D_SH_80350F70; // address written to D_SH_80350F88 -extern OSMesgQueue *D_SH_80350F88; - -extern OSMesg D_SH_80350F8C[1]; -extern OSMesgQueue D_SH_80350F90; // address written to D_SH_80350F90 -extern OSMesgQueue *D_SH_80350FA8; -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) #define UNUSED_COUNT_80333EE8 24 #define AUDIO_HEAP_SIZE 0x2c500 #define AUDIO_INIT_POOL_SIZE 0x2c00 -#else -#define UNUSED_COUNT_80333EE8 16 -#define AUDIO_HEAP_SIZE 0x31150 -#define AUDIO_INIT_POOL_SIZE 0x2500 -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) extern u32 D_SH_80315EF0; extern u16 D_SH_80315EF4; extern u16 D_SH_80315EF8; extern u16 D_SH_80315EFC; -#endif #endif // AUDIO_DATA_H diff --git a/src/audio/shindou_debug_prints.c b/src/audio/sh/debug_prints.c similarity index 99% rename from src/audio/shindou_debug_prints.c rename to src/audio/sh/debug_prints.c index 3088d429..e9591b10 100644 --- a/src/audio/shindou_debug_prints.c +++ b/src/audio/sh/debug_prints.c @@ -1,6 +1,5 @@ #include -#if defined(VERSION_SH) || defined(VERSION_CN) // synthesis.c char shindouDebugPrint1[] = "Terminate-Canceled Channel %d,Phase %d\n"; char shindouDebugPrint2[] = "S->W\n"; @@ -145,4 +144,3 @@ char shindouDebugPrint130[] = "BGLOAD Start %d\n"; char shindouDebugPrint131[] = "Error: OverFlow Your Request\n"; char shindouDebugPrint132[] = "---AudioSending (%d->%d) \n"; // These continue in unk_shindou_audio_file.c -#endif diff --git a/src/audio/effects.c b/src/audio/sh/effects.c similarity index 57% rename from src/audio/effects.c rename to src/audio/sh/effects.c index 4bd17723..3783bbfd 100644 --- a/src/audio/effects.c +++ b/src/audio/sh/effects.c @@ -5,13 +5,6 @@ #include "data.h" #include "seqplayer.h" -#ifdef VERSION_JP -#define US_FLOAT2(x) x##.0 -#else -#define US_FLOAT2(x) x -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 recalculateVolume) { f32 channelVolume; s32 i; @@ -21,11 +14,7 @@ void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 reca if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) { channelVolume = seqChannel->seqPlayer->muteVolumeScale * channelVolume; } -#if defined(VERSION_SH) || defined(VERSION_CN) seqChannel->appliedVolume = channelVolume * channelVolume; -#else - seqChannel->appliedVolume = channelVolume; -#endif } if (seqChannel->changes.as_bitfields.pan) { @@ -55,157 +44,66 @@ void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 reca } seqChannel->changes.as_u8 = 0; } -#else -static void sequence_channel_process_sound(struct SequenceChannel *seqChannel) { - f32 channelVolume; - f32 panLayerWeight; - f32 panFromChannel; - s32 i; - - channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->fadeVolume; - if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) { - channelVolume *= seqChannel->seqPlayer->muteVolumeScale; - } - - panFromChannel = seqChannel->pan * seqChannel->panChannelWeight; - panLayerWeight = US_FLOAT(1.0) - seqChannel->panChannelWeight; - - for (i = 0; i < 4; i++) { - struct SequenceChannelLayer *layer = seqChannel->layers[i]; - if (layer != NULL && layer->enabled && layer->note != NULL) { - layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; - layer->noteVelocity = layer->velocitySquare * channelVolume; - layer->notePan = (layer->pan * panLayerWeight) + panFromChannel; - } - } -} -#endif void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { s32 i; if (seqPlayer->fadeRemainingFrames != 0) { seqPlayer->fadeVolume += seqPlayer->fadeVelocity; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->recalculateVolume = TRUE; -#endif - if (seqPlayer->fadeVolume > US_FLOAT2(1)) { - seqPlayer->fadeVolume = US_FLOAT2(1); + if (seqPlayer->fadeVolume > 1) { + seqPlayer->fadeVolume = 1; } if (seqPlayer->fadeVolume < 0) { seqPlayer->fadeVolume = 0; } if (--seqPlayer->fadeRemainingFrames == 0) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (seqPlayer->state == 2) { sequence_player_disable(seqPlayer); return; } -#else - switch (seqPlayer->state) { - case SEQUENCE_PLAYER_STATE_FADE_OUT: - sequence_player_disable(seqPlayer); - return; - - case SEQUENCE_PLAYER_STATE_2: - case SEQUENCE_PLAYER_STATE_3: - seqPlayer->state = SEQUENCE_PLAYER_STATE_0; - break; - - case SEQUENCE_PLAYER_STATE_4: - break; - } -#endif } } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (seqPlayer->recalculateVolume) { seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; } -#endif // Process channels for (i = 0; i < CHANNELS_MAX; i++) { if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE && seqPlayer->channels[i]->enabled == TRUE) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) sequence_channel_process_sound(seqPlayer->channels[i], seqPlayer->recalculateVolume); -#else - sequence_channel_process_sound(seqPlayer->channels[i]); -#endif } } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->recalculateVolume = FALSE; -#endif } f32 get_portamento_freq_scale(struct Portamento *p) { u32 v0; f32 result; -#if defined(VERSION_JP) || defined(VERSION_US) - if (p->mode == 0) { - return 1.0f; - } -#endif p->cur += p->speed; v0 = (u32) p->cur; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (v0 > 127) -#else - if (v0 >= 127) -#endif { v0 = 127; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 128] - US_FLOAT(1.0)); -#else - result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 127] - US_FLOAT(1.0)); -#endif + result = 1.0f + p->extent * (gPitchBendFrequencyScale[v0 + 128] - 1.0f); return result; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s16 get_vibrato_pitch_change(struct VibratoState *vib) { s32 index; vib->time += (s32) vib->rate; index = (vib->time >> 10) & 0x3F; return vib->curve[index] >> 8; } -#else -s8 get_vibrato_pitch_change(struct VibratoState *vib) { - s32 index; - vib->time += vib->rate; - - index = (vib->time >> 10) & 0x3F; - - switch (index & 0x30) { - case 0x10: - index = 31 - index; - - case 0x00: - return vib->curve[index]; - - case 0x20: - index -= 0x20; - break; - - case 0x30: - index = 63 - index; - break; - } - - return -vib->curve[index]; -} -#endif f32 get_vibrato_freq_scale(struct VibratoState *vib) { s32 pitchChange; @@ -251,59 +149,34 @@ f32 get_vibrato_freq_scale(struct VibratoState *vib) { } pitchChange = get_vibrato_pitch_change(vib); - extent = (f32) vib->extent / US_FLOAT(4096.0); + extent = (f32) vib->extent / 4096.0f; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 128] - US_FLOAT(1.0)); -#else - result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 127] - US_FLOAT(1.0)); -#endif + result = 1.0f + extent * (gPitchBendFrequencyScale[pitchChange + 128] - 1.0f); return result; } void note_vibrato_update(struct Note *note) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (note->portamento.mode != 0) { note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); } if (note->vibratoState.active && note->parentLayer != NO_LAYER) { note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); } -#else - if (note->vibratoState.active) { - note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); - if (note->parentLayer != NO_LAYER) { - note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); - } - } -#endif } void note_vibrato_init(struct Note *note) { struct VibratoState *vib; UNUSED struct SequenceChannel *seqChannel; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) struct NotePlaybackState *seqPlayerState = (struct NotePlaybackState *) ¬e->priority; -#endif note->vibratoFreqScale = 1.0f; note->portamentoFreqScale = 1.0f; vib = ¬e->vibratoState; -#if defined(VERSION_JP) || defined(VERSION_US) - if (note->parentLayer->seqChannel->vibratoExtentStart == 0 - && note->parentLayer->seqChannel->vibratoExtentTarget == 0 - && note->parentLayer->portamento.mode == 0) { - vib->active = FALSE; - return; - } -#endif - vib->active = TRUE; vib->time = 0; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) vib->curve = gWaveSamples[2]; vib->seqChannel = note->parentLayer->seqChannel; if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { @@ -320,67 +193,25 @@ void note_vibrato_init(struct Note *note) { vib->delay = vib->seqChannel->vibratoDelay; seqPlayerState->portamento = seqPlayerState->parentLayer->portamento; -#else - vib->curve = gVibratoCurve; - vib->seqChannel = note->parentLayer->seqChannel; - seqChannel = vib->seqChannel; - - if ((vib->extentChangeTimer = seqChannel->vibratoExtentChangeDelay) == 0) { - vib->extent = seqChannel->vibratoExtentTarget; - } else { - vib->extent = seqChannel->vibratoExtentStart; - } - - if ((vib->rateChangeTimer = seqChannel->vibratoRateChangeDelay) == 0) { - vib->rate = seqChannel->vibratoRateTarget; - } else { - vib->rate = seqChannel->vibratoRateStart; - } - vib->delay = seqChannel->vibratoDelay; - - note->portamento = note->parentLayer->portamento; -#endif } void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, UNUSED s16 *volOut) { adsr->action = 0; adsr->state = ADSR_STATE_DISABLED; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) adsr->delay = 0; adsr->envelope = envelope; -#if defined(VERSION_SH) || defined(VERSION_CN) adsr->sustain = 0.0f; -#endif adsr->current = 0.0f; -#else - adsr->initial = 0; - adsr->delay = 0; - adsr->velocity = 0; - adsr->envelope = envelope; - adsr->volOut = volOut; -#endif } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) f32 adsr_update(struct AdsrState *adsr) { -#else -s32 adsr_update(struct AdsrState *adsr) { -#endif u8 action = adsr->action; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) u8 state = adsr->state; switch (state) { -#else - switch (adsr->state) { -#endif case ADSR_STATE_DISABLED: return 0; case ADSR_STATE_INITIAL: { -#if defined(VERSION_JP) || defined(VERSION_US) - adsr->current = adsr->initial; - adsr->target = adsr->initial; -#endif if (action & ADSR_ACTION_HANG) { adsr->state = ADSR_STATE_HANG; break; @@ -390,15 +221,10 @@ s32 adsr_update(struct AdsrState *adsr) { case ADSR_STATE_START_LOOP: adsr->envIndex = 0; -#if defined(VERSION_JP) || defined(VERSION_US) - adsr->currentHiRes = adsr->current << 0x10; -#endif adsr->state = ADSR_STATE_LOOP; // fallthrough -#if defined(VERSION_SH) || defined(VERSION_CN) restart: -#endif case ADSR_STATE_LOOP: adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay); switch (adsr->delay) { @@ -410,38 +236,23 @@ s32 adsr_update(struct AdsrState *adsr) { break; case ADSR_GOTO: adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg); -#if defined(VERSION_SH) || defined(VERSION_CN) goto restart; -#else - break; -#endif case ADSR_RESTART: adsr->state = ADSR_STATE_INITIAL; break; default: -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (adsr->delay >= 4) { adsr->delay = adsr->delay * gAudioBufferParameters.updatesPerFrame -#if defined(VERSION_SH) || defined(VERSION_CN) / gAudioBufferParameters.presetUnk4 -#endif / 4; } -#if defined(VERSION_SH) || defined(VERSION_CN) if (adsr->delay == 0) { adsr->delay = 1; } adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0f; -#elif defined(VERSION_EU) - adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0; -#endif adsr->target = adsr->target * adsr->target; adsr->velocity = (adsr->target - adsr->current) / adsr->delay; -#else - adsr->target = BSWAP16(adsr->envelope[adsr->envIndex].arg); - adsr->velocity = ((adsr->target - adsr->current) << 0x10) / adsr->delay; -#endif adsr->state = ADSR_STATE_FADE; adsr->envIndex++; break; @@ -452,12 +263,7 @@ s32 adsr_update(struct AdsrState *adsr) { // fallthrough case ADSR_STATE_FADE: -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) adsr->current += adsr->velocity; -#else - adsr->currentHiRes += adsr->velocity; - adsr->current = adsr->currentHiRes >> 0x10; -#endif if (--adsr->delay <= 0) { adsr->state = ADSR_STATE_LOOP; } @@ -469,39 +275,19 @@ s32 adsr_update(struct AdsrState *adsr) { case ADSR_STATE_DECAY: case ADSR_STATE_RELEASE: { adsr->current -= adsr->fadeOutVel; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { -#else - if (adsr->sustain != 0 && adsr->state == ADSR_STATE_DECAY) { -#endif if (adsr->current < adsr->sustain) { adsr->current = adsr->sustain; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) adsr->delay = 128; -#else - adsr->delay = adsr->sustain / 16; -#endif adsr->state = ADSR_STATE_SUSTAIN; } break; } -#if defined(VERSION_SH) || defined(VERSION_CN) if (adsr->current < 0.00001f) { adsr->current = 0.0f; adsr->state = ADSR_STATE_DISABLED; } -#elif defined(VERSION_EU) - if (adsr->current < 0) { - adsr->current = 0.0f; - adsr->state = ADSR_STATE_DISABLED; - } -#else - if (adsr->current < 100) { - adsr->current = 0; - adsr->state = ADSR_STATE_DISABLED; - } -#endif break; } @@ -520,14 +306,9 @@ s32 adsr_update(struct AdsrState *adsr) { if ((action & ADSR_ACTION_RELEASE)) { adsr->state = ADSR_STATE_RELEASE; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) adsr->action = action & ~ADSR_ACTION_RELEASE; -#else - adsr->action = action & ~(ADSR_ACTION_RELEASE | ADSR_ACTION_DECAY); -#endif } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (adsr->current < 0.0f) { return 0.0f; } @@ -536,8 +317,4 @@ s32 adsr_update(struct AdsrState *adsr) { return 1.0f; } return adsr->current; -#else - *adsr->volOut = adsr->current; - return 0; -#endif } diff --git a/src/audio/sh/effects.h b/src/audio/sh/effects.h new file mode 100644 index 00000000..cdedf1e4 --- /dev/null +++ b/src/audio/sh/effects.h @@ -0,0 +1,42 @@ +#ifndef AUDIO_EFFECTS_H +#define AUDIO_EFFECTS_H + +#include + +#include "internal.h" +#include "platform_info.h" + +#define ADSR_STATE_DISABLED 0 +#define ADSR_STATE_INITIAL 1 +#define ADSR_STATE_START_LOOP 2 +#define ADSR_STATE_LOOP 3 +#define ADSR_STATE_FADE 4 +#define ADSR_STATE_HANG 5 +#define ADSR_STATE_DECAY 6 +#define ADSR_STATE_RELEASE 7 +#define ADSR_STATE_SUSTAIN 8 + +#define ADSR_ACTION_RELEASE 0x10 +#define ADSR_ACTION_DECAY 0x20 +#define ADSR_ACTION_HANG 0x40 + +#define ADSR_DISABLE 0 +#define ADSR_HANG -1 +#define ADSR_GOTO -2 +#define ADSR_RESTART -3 + +// Envelopes are always stored as big endian, to match sequence files which are +// byte blobs and can embed envelopes. Hence this byteswapping macro. +#if IS_BIG_ENDIAN +#define BSWAP16(x) (x) +#else +#define BSWAP16(x) (((x) & 0xff) << 8 | (((x) >> 8) & 0xff)) +#endif + +void sequence_player_process_sound(struct SequencePlayer *seqPlayer); +void note_vibrato_update(struct Note *note); +void note_vibrato_init(struct Note *note); +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut); +f32 adsr_update(struct AdsrState *adsr); + +#endif // AUDIO_EFFECTS_H diff --git a/src/audio/sh/globals_start.c b/src/audio/sh/globals_start.c new file mode 100644 index 00000000..01498f2a --- /dev/null +++ b/src/audio/sh/globals_start.c @@ -0,0 +1,3 @@ +#include + +u64 gAudioGlobalsStartMarker; diff --git a/src/audio/heap.c b/src/audio/sh/heap.c similarity index 62% rename from src/audio/heap.c rename to src/audio/sh/heap.c index 5b23438b..d6ac823d 100644 --- a/src/audio/heap.c +++ b/src/audio/sh/heap.c @@ -21,12 +21,6 @@ struct PoolSplit2 { u32 wantTemporary; }; // size = 0x8 -#if defined(VERSION_JP) || defined(VERSION_US) -s16 gVolume; -s8 gReverbDownsampleRate; -u8 sReverbDownsampleRateLog; // never read -#endif - struct SoundAllocPool gAudioSessionPool; struct SoundAllocPool gAudioInitPool; struct SoundAllocPool gNotesAndBuffersPool; @@ -39,34 +33,27 @@ struct SoundMultiPool gSeqLoadedPool; struct SoundMultiPool gBankLoadedPool; struct SoundMultiPool gUnusedLoadedPool; -#if defined(VERSION_SH) || defined(VERSION_CN) struct Unk1Pool gUnkPool1; struct UnkPool gUnkPool2; struct UnkPool gUnkPool3; -#endif struct PoolSplit sSessionPoolSplit; struct PoolSplit2 sSeqAndBankPoolSplit; struct PoolSplit sPersistentCommonPoolSplit; struct PoolSplit sTemporaryCommonPoolSplit; -#if defined(VERSION_SH) || defined(VERSION_CN) u8 gUnkLoadStatus[0x40]; -#endif u8 gBankLoadStatus[0x40]; u8 gSeqLoadStatus[0x100]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) volatile u8 gAudioResetStatus; u8 gAudioResetPresetIdToLoad; s32 gAudioResetFadeOutFramesLeft; -#endif u8 gAudioUnusedBuffer[0x1000]; extern s32 gMaxAudioCmds; -#if defined(VERSION_SH) || defined(VERSION_CN) void *get_bank_or_seq_inner(s32 poolIdx, s32 arg1, s32 bankId); struct UnkEntry *func_sh_802f1ec4(u32 size); void func_sh_802f2158(struct UnkEntry *entry); @@ -75,100 +62,10 @@ void func_sh_802F2320(struct UnkEntry *entry, struct AudioBankSample *sample); void func_sh_802f23ec(void); void unk_pools_init(u32 size1, u32 size2); -#endif - -#if defined(VERSION_EU) -/** - * Assuming 'k' in [9, 24], - * Computes a newton's method step for f(x) = x^k - d - */ -f64 root_newton_step(f64 x, s32 k, f64 d) { - f64 deg2 = x * x; - f64 deg4 = deg2 * deg2; - f64 deg8 = deg4 * deg4; - s32 degree = k - 9; - f64 fx; - - f64 deriv = deg8; - if (degree & 1) { - deriv *= x; - } - if (degree & 2) { - deriv *= deg2; - } - if (degree & 4) { - deriv *= deg4; - } - if (degree & 8) { - deriv *= deg8; - } - fx = deriv * x - d; - deriv = k * deriv; - return x - fx / deriv; -} - -/** - * Assuming 'k' in [9, 24], - * Computes d ^ (1/k) - * - * @return the root, or 1.0 if d is 0 - */ -f64 kth_root(f64 d, s32 k) { - f64 root = 1.5; - f64 next; - f64 diff; - s32 i; - if (d == 0.0) { - root = 1.0; - } else { - for (i = 0; i < 64; i++) { - if (1) { - } - next = root_newton_step(root, k, d); - diff = next - root; - - if (diff < 0) { - diff = -diff; - } - - if (diff < 1e-07) { - root = next; - break; - } else { - root = next; - } - } - } - - return root; -} - -void build_vol_rampings_table(s32 UNUSED unused, s32 len) { - s32 i; - s32 step; - s32 d; - s32 k = len / 8; - - for (step = 0, i = 0; i < 0x400; step += 32, i++) { - d = step; - if (step == 0) { - d = 1; - } - - gLeftVolRampings[0][i] = kth_root( d, k - 1); - gRightVolRampings[0][i] = kth_root(1.0 / d, k - 1) * 65536.0; - gLeftVolRampings[1][i] = kth_root( d, k); - gRightVolRampings[1][i] = kth_root(1.0 / d, k) * 65536.0; - gLeftVolRampings[2][i] = kth_root( d, k + 1); - gRightVolRampings[2][i] = kth_root(1.0 / d, k + 1) * 65536.0; - } -} -#endif void reset_bank_and_seq_load_status(void) { s32 i; -#if defined(VERSION_SH) || defined(VERSION_CN) for (i = 0; i < 64; i++) { if (gBankLoadStatus[i] != SOUND_LOAD_STATUS_5) { gBankLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; @@ -186,15 +83,6 @@ void reset_bank_and_seq_load_status(void) { gSeqLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; } } -#else - for (i = 0; i < 64; i++) { - gBankLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; - } - - for (i = 0; i < 256; i++) { - gSeqLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; - } -#endif } void discard_bank(s32 bankId) { @@ -203,24 +91,16 @@ void discard_bank(s32 bankId) { for (i = 0; i < gMaxSimultaneousNotes; i++) { struct Note *note = &gNotes[i]; -#if defined(VERSION_EU) - if (note->noteSubEu.bankId == bankId) -#else if (note->bankId == bankId) -#endif { // (These prints are unclear. Arguments are picked semi-randomly.) eu_stubbed_printf_1("Warning:Kill Note %x \n", i); -#if defined(VERSION_SH) || defined(VERSION_CN) if (note->unkSH34 == NOTE_PRIORITY_DISABLED && note->priority) -#else - if (note->priority >= NOTE_PRIORITY_MIN) -#endif { eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId, bankId, note->priority); eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n"); - note->parentLayer->enabled = FALSE; // is 0x48, should be 0x44 + note->parentLayer->enabled = FALSE; note->parentLayer->finished = TRUE; } note_disable(note); @@ -235,17 +115,12 @@ void discard_sequence(s32 seqId) { for (i = 0; i < SEQUENCE_PLAYERS; i++) { if (gSequencePlayers[i].enabled && gSequencePlayers[i].seqId == seqId) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) sequence_player_disable(&gSequencePlayers[i]); -#else - sequence_player_disable(gSequencePlayers + i); -#endif } } } void *soundAlloc(struct SoundAllocPool *pool, u32 size) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) u8 *start; u8 *pos; u32 alignedSize = ALIGN16(size); @@ -260,30 +135,10 @@ void *soundAlloc(struct SoundAllocPool *pool, u32 size) { eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size); return NULL; } -#if defined(VERSION_SH) || defined(VERSION_CN) pool->numAllocatedEntries++; -#endif return start; -#else - u8 *start; - s32 last; - s32 i; - - if ((pool->cur + ALIGN16(size) <= pool->size + pool->start)) { - start = pool->cur; - pool->cur += ALIGN16(size); - last = pool->cur - start - 1; - for (i = 0; i <= last; i++) { - start[i] = 0; - } - } else { - return NULL; - } - return start; -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) void *sound_alloc_uninitialized(struct SoundAllocPool *pool, u32 size) { u8 *start; u32 alignedSize = ALIGN16(size); @@ -298,15 +153,10 @@ void *sound_alloc_uninitialized(struct SoundAllocPool *pool, u32 size) { pool->numAllocatedEntries++; return start; } -#endif void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size) { pool->cur = pool->start = (u8 *) ALIGN16((uintptr_t) memAddr); -#if defined(VERSION_SH) || defined(VERSION_CN) pool->size = size - ((uintptr_t) memAddr & 0xf); -#else - pool->size = size; -#endif pool->numAllocatedEntries = 0; } @@ -321,12 +171,8 @@ void temporary_pool_clear(struct TemporaryPool *temporary) { temporary->pool.cur = temporary->pool.start; temporary->nextSide = 0; temporary->entries[0].ptr = temporary->pool.start; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) temporary->entries[1].ptr = temporary->pool.start + temporary->pool.size; -#else - temporary->entries[1].ptr = temporary->pool.size + temporary->pool.start; -#endif - temporary->entries[0].id = -1; // should be at 1e not 1c + temporary->entries[0].id = -1; temporary->entries[1].id = -1; } @@ -341,30 +187,23 @@ void sound_init_main_pools(s32 sizeForAudioInitPool) { sound_alloc_pool_init(&gAudioSessionPool, gAudioHeap + sizeForAudioInitPool, gAudioHeapSize - sizeForAudioInitPool); } -#if defined(VERSION_SH) || defined(VERSION_CN) -#define SOUND_ALLOC_FUNC sound_alloc_uninitialized -#else -#define SOUND_ALLOC_FUNC soundAlloc -#endif - void session_pools_init(struct PoolSplit *a) { gAudioSessionPool.cur = gAudioSessionPool.start; - sound_alloc_pool_init(&gNotesAndBuffersPool, SOUND_ALLOC_FUNC(&gAudioSessionPool, a->wantSeq), a->wantSeq); - sound_alloc_pool_init(&gSeqAndBankPool, SOUND_ALLOC_FUNC(&gAudioSessionPool, a->wantCustom), a->wantCustom); + sound_alloc_pool_init(&gNotesAndBuffersPool, sound_alloc_uninitialized(&gAudioSessionPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gSeqAndBankPool, sound_alloc_uninitialized(&gAudioSessionPool, a->wantCustom), a->wantCustom); } void seq_and_bank_pool_init(struct PoolSplit2 *a) { gSeqAndBankPool.cur = gSeqAndBankPool.start; - sound_alloc_pool_init(&gPersistentCommonPool, SOUND_ALLOC_FUNC(&gSeqAndBankPool, a->wantPersistent), a->wantPersistent); - sound_alloc_pool_init(&gTemporaryCommonPool, SOUND_ALLOC_FUNC(&gSeqAndBankPool, a->wantTemporary), a->wantTemporary); + sound_alloc_pool_init(&gPersistentCommonPool, sound_alloc_uninitialized(&gSeqAndBankPool, a->wantPersistent), a->wantPersistent); + sound_alloc_pool_init(&gTemporaryCommonPool, sound_alloc_uninitialized(&gSeqAndBankPool, a->wantTemporary), a->wantTemporary); } void persistent_pools_init(struct PoolSplit *a) { gPersistentCommonPool.cur = gPersistentCommonPool.start; - sound_alloc_pool_init(&gSeqLoadedPool.persistent.pool, SOUND_ALLOC_FUNC(&gPersistentCommonPool, a->wantSeq), a->wantSeq); - sound_alloc_pool_init(&gBankLoadedPool.persistent.pool, SOUND_ALLOC_FUNC(&gPersistentCommonPool, a->wantBank), a->wantBank); - sound_alloc_pool_init(&gUnusedLoadedPool.persistent.pool, SOUND_ALLOC_FUNC(&gPersistentCommonPool, a->wantUnused), - a->wantUnused); + sound_alloc_pool_init(&gSeqLoadedPool.persistent.pool, sound_alloc_uninitialized(&gPersistentCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.persistent.pool, sound_alloc_uninitialized(&gPersistentCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.persistent.pool, sound_alloc_uninitialized(&gPersistentCommonPool, a->wantUnused), a->wantUnused); persistent_pool_clear(&gSeqLoadedPool.persistent); persistent_pool_clear(&gBankLoadedPool.persistent); persistent_pool_clear(&gUnusedLoadedPool.persistent); @@ -372,58 +211,27 @@ void persistent_pools_init(struct PoolSplit *a) { void temporary_pools_init(struct PoolSplit *a) { gTemporaryCommonPool.cur = gTemporaryCommonPool.start; - sound_alloc_pool_init(&gSeqLoadedPool.temporary.pool, SOUND_ALLOC_FUNC(&gTemporaryCommonPool, a->wantSeq), a->wantSeq); - sound_alloc_pool_init(&gBankLoadedPool.temporary.pool, SOUND_ALLOC_FUNC(&gTemporaryCommonPool, a->wantBank), a->wantBank); - sound_alloc_pool_init(&gUnusedLoadedPool.temporary.pool, SOUND_ALLOC_FUNC(&gTemporaryCommonPool, a->wantUnused), - a->wantUnused); + sound_alloc_pool_init(&gSeqLoadedPool.temporary.pool, sound_alloc_uninitialized(&gTemporaryCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.temporary.pool, sound_alloc_uninitialized(&gTemporaryCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.temporary.pool, sound_alloc_uninitialized(&gTemporaryCommonPool, a->wantUnused), a->wantUnused); temporary_pool_clear(&gSeqLoadedPool.temporary); temporary_pool_clear(&gBankLoadedPool.temporary); temporary_pool_clear(&gUnusedLoadedPool.temporary); } -#undef SOUND_ALLOC_FUNC -#if defined(VERSION_JP) || defined(VERSION_US) -UNUSED static void unused_803163D4(void) { -} -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) void *alloc_bank_or_seq(s32 poolIdx, s32 size, s32 arg3, s32 id) { -#else -void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) { -#endif // arg3 = 0, 1 or 2? -#if defined(VERSION_SH) || defined(VERSION_CN) struct SoundMultiPool *arg0; -#define isSound poolIdx -#endif struct TemporaryPool *tp; struct SoundAllocPool *pool; void *ret; -#if defined(VERSION_JP) || defined(VERSION_US) - u16 UNUSED _firstVal; - u16 UNUSED _secondVal; -#else u16 firstVal; u16 secondVal; -#endif u32 nullID = -1; UNUSED s32 i; u8 *table; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - u8 isSound; -#endif -#if defined(VERSION_JP) || defined(VERSION_US) - u16 firstVal; - u16 secondVal; - u32 bothDiscardable; - u32 leftDiscardable, rightDiscardable; - u32 leftNotLoaded, rightNotLoaded; - u32 leftAvail, rightAvail; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) switch (poolIdx) { case 0: arg0 = &gSeqLoadedPool; @@ -440,21 +248,10 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg table = gUnkLoadStatus; break; } -#endif if (arg3 == 0) { tp = &arg0->temporary; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - if (arg0 == &gSeqLoadedPool) { - table = gSeqLoadStatus; - isSound = FALSE; - } else if (arg0 == &gBankLoadedPool) { - table = gBankLoadStatus; - isSound = TRUE; - } -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) if (tp->entries[0].id == (s8)nullID) { firstVal = SOUND_LOAD_STATUS_NOT_LOADED; } else { @@ -465,49 +262,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } else { secondVal = table[tp->entries[1].id]; } -#else - firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]); - secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]); -#endif -#if defined(VERSION_JP) || defined(VERSION_US) - leftNotLoaded = (firstVal == SOUND_LOAD_STATUS_NOT_LOADED); - leftDiscardable = (firstVal == SOUND_LOAD_STATUS_DISCARDABLE); - leftAvail = (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS); - rightNotLoaded = (secondVal == SOUND_LOAD_STATUS_NOT_LOADED); - rightDiscardable = (secondVal == SOUND_LOAD_STATUS_DISCARDABLE); - rightAvail = (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS); - bothDiscardable = (leftDiscardable && rightDiscardable); - - if (leftNotLoaded) { - tp->nextSide = 0; - } else if (rightNotLoaded) { - tp->nextSide = 1; - } else if (bothDiscardable) { - // Use the opposite side from last time. - } else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { // ??! (I blame copt) - tp->nextSide = 0; - } else if (rightDiscardable) { - tp->nextSide = 1; - } else if (leftAvail) { - tp->nextSide = 0; - } else if (rightAvail) { - tp->nextSide = 1; - } else { - // Both left and right sides are being loaded into. - return NULL; - } -#else -#ifdef VERSION_EU - if (0) { - // It's unclear where these string literals go. - eu_stubbed_printf_0("DataHeap Not Allocate \n"); - eu_stubbed_printf_1("StayHeap Not Allocate %d\n", 0); - eu_stubbed_printf_1("AutoHeap Not Allocate %d\n", 0); - } -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) if (poolIdx == 1) { if (firstVal == SOUND_LOAD_STATUS_4) { for (i = 0; i < gMaxSimultaneousNotes; i++) { @@ -536,7 +291,6 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } } } -#endif if (firstVal == SOUND_LOAD_STATUS_NOT_LOADED) { tp->nextSide = 0; @@ -551,19 +305,6 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) { tp->nextSide = 1; } else { -#ifdef VERSION_EU - eu_stubbed_printf_0("WARNING: NO STOP AUTO AREA.\n"); - eu_stubbed_printf_0(" AND TRY FORCE TO STOP SIDE \n"); - if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) { - tp->nextSide = 0; - } else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) { - tp->nextSide = 1; - } else { - // Both left and right sides are being loaded into. - eu_stubbed_printf_0("TWO SIDES ARE LOADING... ALLOC CANCELED.\n"); - return NULL; - } -#else if (poolIdx == 0) { if (firstVal == SOUND_LOAD_STATUS_COMPLETE) { for (i = 0; i < SEQUENCE_PLAYERS; i++) { @@ -632,15 +373,13 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } return NULL; out:; -#endif } } -#endif pool = &arg0->temporary.pool; if (tp->entries[tp->nextSide].id != (s8)nullID) { table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED; - if (isSound == TRUE) { + if (poolIdx == 1) { discard_bank(tp->entries[tp->nextSide].id); } } @@ -653,9 +392,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg pool->cur = pool->start + size; -#if defined(VERSION_SH) || defined(VERSION_CN) if (tp->entries[1].id != (s32)nullID) -#endif if (tp->entries[1].ptr < pool->cur) { eu_stubbed_printf_0("WARNING: Before Area Overlaid After."); @@ -663,50 +400,38 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg // (possible @bug: what if it's currently being loaded?) table[tp->entries[1].id] = SOUND_LOAD_STATUS_NOT_LOADED; - switch (isSound) { - case FALSE: + switch (poolIdx) { + case 0: discard_sequence(tp->entries[1].id); break; - case TRUE: + case 1: discard_bank(tp->entries[1].id); break; } tp->entries[1].id = (s32)nullID; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) tp->entries[1].ptr = pool->start + pool->size; -#else - tp->entries[1].ptr = pool->size + pool->start; -#endif } ret = tp->entries[0].ptr; break; case 1: -#if defined(VERSION_SH) || defined(VERSION_CN) tp->entries[1].ptr = (u8 *) ((uintptr_t) (pool->start + pool->size - size) & ~0x0f); -#elif defined(VERSION_EU) - tp->entries[1].ptr = pool->start + pool->size - size - 0x10; -#else - tp->entries[1].ptr = pool->size + pool->start - size - 0x10; -#endif tp->entries[1].id = id; tp->entries[1].size = size; -#if defined(VERSION_SH) || defined(VERSION_CN) if (tp->entries[0].id != (s32)nullID) -#endif if (tp->entries[1].ptr < pool->cur) { eu_stubbed_printf_0("WARNING: After Area Overlaid Before."); table[tp->entries[0].id] = SOUND_LOAD_STATUS_NOT_LOADED; - switch (isSound) { - case FALSE: + switch (poolIdx) { + case 0: discard_sequence(tp->entries[0].id); break; - case TRUE: + case 1: discard_bank(tp->entries[0].id); break; } @@ -730,37 +455,16 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg return ret; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#if defined(VERSION_SH) || defined(VERSION_CN) ret = sound_alloc_uninitialized(&arg0->persistent.pool, size); -#else - ret = soundAlloc(&arg0->persistent.pool, arg1 * size); -#endif arg0->persistent.entries[arg0->persistent.numEntries].ptr = ret; if (ret == NULL) -#else - arg0->persistent.entries[arg0->persistent.numEntries].ptr = soundAlloc(&arg0->persistent.pool, arg1 * size); - - if (arg0->persistent.entries[arg0->persistent.numEntries].ptr == NULL) -#endif { switch (arg3) { case 2: -#if defined(VERSION_EU) - eu_stubbed_printf_0("MEMORY:StayHeap OVERFLOW."); - return alloc_bank_or_seq(arg0, arg1, size, 0, id); -#elif defined(VERSION_SH) || defined(VERSION_CN) return alloc_bank_or_seq(poolIdx, size, 0, id); -#else - // Prevent tail call optimization. - ret = alloc_bank_or_seq(arg0, arg1, size, 0, id); - return ret; -#endif case 1: -#if defined(VERSION_SH) || defined(VERSION_CN) case 0: -#endif eu_stubbed_printf_1("MEMORY:StayHeap OVERFLOW (REQ:%d)", arg1 * size); return NULL; } @@ -770,17 +474,9 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg // Because the buffer is small enough that more don't fit? arg0->persistent.entries[arg0->persistent.numEntries].id = id; arg0->persistent.entries[arg0->persistent.numEntries].size = size; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) return arg0->persistent.entries[arg0->persistent.numEntries++].ptr; -#else - arg0->persistent.numEntries++; return arg0->persistent.entries[arg0->persistent.numEntries - 1].ptr; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) -#undef isSound -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) void *get_bank_or_seq(s32 poolIdx, s32 arg1, s32 id) { void *ret; @@ -836,49 +532,7 @@ void *get_bank_or_seq_inner(s32 poolIdx, s32 arg1, s32 bankId) { } return NULL; } -#endif -#if !defined(VERSION_SH) && !defined(VERSION_CN) -void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) { - u32 i; - UNUSED void *ret; - struct TemporaryPool *temporary = &arg0->temporary; - if (arg1 == 0) { - // Try not to overwrite sound that we have just accessed, by setting nextSide appropriately. - if (temporary->entries[0].id == id) { - temporary->nextSide = 1; - return temporary->entries[0].ptr; - } else if (temporary->entries[1].id == id) { - temporary->nextSide = 0; - return temporary->entries[1].ptr; - } - eu_stubbed_printf_1("Auto Heap Unhit for ID %d\n", id); - return NULL; - } else { - struct PersistentPool *persistent = &arg0->persistent; - for (i = 0; i < persistent->numEntries; i++) { - if (id == persistent->entries[i].id) { - eu_stubbed_printf_2("Cache hit %d at stay %d\n", id, i); - return persistent->entries[i].ptr; - } - } - - if (arg1 == 2) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - return get_bank_or_seq(arg0, 0, id); -#else - // Prevent tail call optimization by using a temporary. - // Either copt or -Wo,-notail. - ret = get_bank_or_seq(arg0, 0, id); - return ret; -#endif - } - return NULL; - } -} -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) { s32 i; f32 tmp[16]; @@ -897,22 +551,8 @@ void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) { for (i = 0; i < 16; i++) { arg2[i] = tmp[i]; } - -#ifdef VERSION_EU - for (i = 0; i < 8; i++) { - eu_stubbed_printf_1("%d ", arg2[i]); - } - eu_stubbed_printf_0("\n"); - - for (i = 8; i < 16; i++) { - eu_stubbed_printf_1("%d ", arg2[i]); - } - eu_stubbed_printf_0("\n"); -#endif } -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) void fill_zero_filter(s16 filter[]) { s32 i; for (i = 0; i < 8; i++) { @@ -953,17 +593,8 @@ void fill_filter(s16 filter[8], s32 arg1, s32 arg2) { } } } -#endif void decrease_reverb_gain(void) { -#if defined(VERSION_EU) - s32 i; - for (i = 0; i < gNumSynthesisReverbs; i++) { - gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 8; - } -#elif defined(VERSION_JP) || defined(VERSION_US) - gSynthesisReverb.reverbGain -= gSynthesisReverb.reverbGain / 4; -#else s32 i, j; s32 v0 = gAudioBufferParameters.presetUnk4 == 2 ? 2 : 1; for (i = 0; i < gNumSynthesisReverbs; i++) { @@ -971,10 +602,8 @@ void decrease_reverb_gain(void) { gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 3; } } -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) void clear_curr_ai_buffer(void) { s32 currIndex = gCurrAiBufferIndex; s32 i; @@ -983,27 +612,19 @@ void clear_curr_ai_buffer(void) { gAiBuffers[currIndex][i] = 0; } } -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 audio_shut_down_and_reset_step(void) { s32 i; s32 j; -#if defined(VERSION_SH) || defined(VERSION_CN) s32 num = gAudioBufferParameters.presetUnk4 == 2 ? 2 : 1; -#endif switch (gAudioResetStatus) { case 5: for (i = 0; i < SEQUENCE_PLAYERS; i++) { sequence_player_disable(&gSequencePlayers[i]); } -#if defined(VERSION_SH) || defined(VERSION_CN) gAudioResetFadeOutFramesLeft = 4 / num; -#else - gAudioResetFadeOutFramesLeft = 4; -#endif gAudioResetStatus--; break; case 4: @@ -1017,21 +638,15 @@ s32 audio_shut_down_and_reset_step(void) { gNotes[i].adsr.action |= ADSR_ACTION_RELEASE; } } -#if defined(VERSION_SH) || defined(VERSION_CN) gAudioResetFadeOutFramesLeft = 16 / num; -#else - gAudioResetFadeOutFramesLeft = 16; -#endif gAudioResetStatus--; } break; case 3: if (gAudioResetFadeOutFramesLeft != 0) { gAudioResetFadeOutFramesLeft--; -#if defined(VERSION_SH) || defined(VERSION_CN) if (1) { } -#endif decrease_reverb_gain(); } else { for (i = 0; i < NUMAIBUFFERS; i++) { @@ -1039,169 +654,62 @@ s32 audio_shut_down_and_reset_step(void) { gAiBuffers[i][j] = 0; } } -#if defined(VERSION_SH) || defined(VERSION_CN) gAudioResetFadeOutFramesLeft = 4 / num; -#else - gAudioResetFadeOutFramesLeft = 4; -#endif gAudioResetStatus--; } break; case 2: -#if defined(VERSION_SH) || defined(VERSION_CN) clear_curr_ai_buffer(); -#endif if (gAudioResetFadeOutFramesLeft != 0) { gAudioResetFadeOutFramesLeft--; } else { gAudioResetStatus--; -#if defined(VERSION_SH) || defined(VERSION_CN) func_sh_802f23ec(); -#endif } break; case 1: audio_reset_session(); gAudioResetStatus = 0; -#if defined(VERSION_SH) || defined(VERSION_CN) for (i = 0; i < NUMAIBUFFERS; i++) { gAiBufferLengths[i] = gAudioBufferParameters.maxAiBufferLength; for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { gAiBuffers[i][j] = 0; } } -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) if (gAudioResetFadeOutFramesLeft) { } -#endif if (gAudioResetStatus < 3) { return 0; } return 1; } -#else -/** - * Waits until a specified number of audio frames have been created - */ -void wait_for_audio_frames(s32 frames) { - gAudioFrameCount = 0; - // Sound thread will update gAudioFrameCount - while (gAudioFrameCount < frames) { - // spin - } -} -#endif -#if defined(VERSION_JP) || defined(VERSION_US) -void audio_reset_session(struct AudioSessionSettings *preset) { -#else void audio_reset_session(void) { struct AudioSessionSettingsEU *preset = &gAudioSessionPresets[gAudioResetPresetIdToLoad]; struct ReverbSettingsEU *reverbSettings; -#endif s16 *mem; -#if defined(VERSION_JP) || defined(VERSION_US) - s8 updatesPerFrame; - s32 reverbWindowSize; - s32 k; -#endif s32 i; s32 j; s32 persistentMem; s32 temporaryMem; s32 totalMem; s32 wantMisc; -#if defined(VERSION_JP) || defined(VERSION_US) - s32 frames; - s32 remainingDmas; -#else struct SynthesisReverb *reverb; -#endif eu_stubbed_printf_1("Heap Reconstruct Start %x\n", gAudioResetPresetIdToLoad); -#if defined(VERSION_JP) || defined(VERSION_US) - if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { - decrease_reverb_gain(); - for (i = 0; i < gMaxSimultaneousNotes; i++) { - if (gNotes[i].enabled && gNotes[i].adsr.state != ADSR_STATE_DISABLED) { - gNotes[i].adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; - gNotes[i].adsr.action |= ADSR_ACTION_RELEASE; - } - } - - // Wait for all notes to stop playing - frames = 0; - for (;;) { - wait_for_audio_frames(1); - frames++; - if (frames > 4 * 60) { - // Break after 4 seconds - break; - } - - for (i = 0; i < gMaxSimultaneousNotes; i++) { - if (gNotes[i].enabled) { - break; - } - } - - if (i == gMaxSimultaneousNotes) { - // All zero, break early - break; - } - } - - // Wait for the reverb to finish as well - decrease_reverb_gain(); - wait_for_audio_frames(3); - - // The audio interface is double buffered; thus, we have to take the - // load lock for 2 frames for the buffers to free up before we can - // repurpose memory. Make that 3 frames, just in case. - gAudioLoadLock = AUDIO_LOCK_LOADING; - wait_for_audio_frames(3); - - remainingDmas = gCurrAudioFrameDmaCount; - while (remainingDmas > 0) { - for (i = 0; i < gCurrAudioFrameDmaCount; i++) { - if (osRecvMesg(&gCurrAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK) == 0) - remainingDmas--; - } - } - gCurrAudioFrameDmaCount = 0; - - for (j = 0; j < NUMAIBUFFERS; j++) { - for (k = 0; k < (s32) (AIBUFFER_LEN / sizeof(s16)); k++) { - gAiBuffers[j][k] = 0; - } - } - } -#endif - gSampleDmaNumListItems = 0; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) gAudioBufferParameters.frequency = preset->frequency; gAudioBufferParameters.aiFrequency = osAiSetFrequency(gAudioBufferParameters.frequency); gAudioBufferParameters.samplesPerFrameTarget = ALIGN16(gAudioBufferParameters.frequency / gRefreshRate); gAudioBufferParameters.minAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget - 0x10; gAudioBufferParameters.maxAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget + 0x10; -#if defined(VERSION_SH) || defined(VERSION_CN) gAudioBufferParameters.updatesPerFrame = (gAudioBufferParameters.samplesPerFrameTarget + 0x10) / 192 + 1; gAudioBufferParameters.samplesPerUpdate = (gAudioBufferParameters.samplesPerFrameTarget / gAudioBufferParameters.updatesPerFrame) & -8; -#else - gAudioBufferParameters.updatesPerFrame = (gAudioBufferParameters.samplesPerFrameTarget + 0x10) / 160 + 1; - gAudioBufferParameters.samplesPerUpdate = (gAudioBufferParameters.samplesPerFrameTarget / gAudioBufferParameters.updatesPerFrame) & 0xfff8; -#endif gAudioBufferParameters.samplesPerUpdateMax = gAudioBufferParameters.samplesPerUpdate + 8; gAudioBufferParameters.samplesPerUpdateMin = gAudioBufferParameters.samplesPerUpdate - 8; gAudioBufferParameters.resampleRate = 32000.0f / FLOAT_CAST(gAudioBufferParameters.frequency); -#if defined(VERSION_SH) || defined(VERSION_CN) gAudioBufferParameters.unkUpdatesPerFrameScaled = (1.0f / 256.0f) / gAudioBufferParameters.updatesPerFrame; -#else - gAudioBufferParameters.unkUpdatesPerFrameScaled = (3.0f / 1280.0f) / gAudioBufferParameters.updatesPerFrame; -#endif gAudioBufferParameters.updatesPerFrameInv = 1.0f / gAudioBufferParameters.updatesPerFrame; gMaxSimultaneousNotes = preset->maxSimultaneousNotes; @@ -1214,68 +722,13 @@ void audio_reset_session(void) { gAudioBufferParameters.minAiBufferLength *= gAudioBufferParameters.presetUnk4; gAudioBufferParameters.updatesPerFrame *= gAudioBufferParameters.presetUnk4; -#if defined(VERSION_SH) || defined(VERSION_CN) if (gAudioBufferParameters.presetUnk4 >= 2) { gAudioBufferParameters.maxAiBufferLength -= 0x10; } gMaxAudioCmds = gMaxSimultaneousNotes * 0x14 * gAudioBufferParameters.updatesPerFrame + preset->numReverbs * 0x20 + 0x1E0; -#else - gMaxAudioCmds = gMaxSimultaneousNotes * 0x10 * gAudioBufferParameters.updatesPerFrame + preset->numReverbs * 0x20 + 0x300; -#endif -#else - reverbWindowSize = preset->reverbWindowSize; - gAiFrequency = osAiSetFrequency(preset->frequency); - gMaxSimultaneousNotes = preset->maxSimultaneousNotes; - gSamplesPerFrameTarget = ALIGN16(gAiFrequency / 60); - gReverbDownsampleRate = preset->reverbDownsampleRate; - switch (gReverbDownsampleRate) { - case 1: - sReverbDownsampleRateLog = 0; - break; - case 2: - sReverbDownsampleRateLog = 1; - break; - case 4: - sReverbDownsampleRateLog = 2; - break; - case 8: - sReverbDownsampleRateLog = 3; - break; - case 16: - sReverbDownsampleRateLog = 4; - break; - default: - sReverbDownsampleRateLog = 0; - } - - gReverbDownsampleRate = preset->reverbDownsampleRate; - gVolume = preset->volume; - gMinAiBufferLength = gSamplesPerFrameTarget - 0x10; - updatesPerFrame = gSamplesPerFrameTarget / 160 + 1; - gAudioUpdatesPerFrame = gSamplesPerFrameTarget / 160 + 1; - - // Compute conversion ratio from the internal unit tatums/tick to the - // external beats/minute (JP) or tatums/minute (US). In practice this is - // 300 on JP and 14360 on US. -#ifdef VERSION_JP - gTempoInternalToExternal = updatesPerFrame * 3600 / gTatumsPerBeat; -#else - gTempoInternalToExternal = (u32)(updatesPerFrame * 2880000.0f / gTatumsPerBeat / 16.713f); -#endif - gMaxAudioCmds = gMaxSimultaneousNotes * 20 * updatesPerFrame + 320; -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem + preset->persistentBankMem + preset->unk18 + preset->unkMem28 + 0x10); temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem + preset->temporaryBankMem + preset->unk24 + preset->unkMem2C + 0x10); -#elif defined(VERSION_EU) - persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem + preset->persistentBankMem); - temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem + preset->temporaryBankMem); -#else - persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentBankMem + preset->persistentSeqMem); - temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporaryBankMem + preset->temporarySeqMem); -#endif totalMem = persistentMem + temporaryMem; wantMisc = gAudioSessionPool.size - totalMem - 0x100; sSessionPoolSplit.wantSeq = wantMisc; @@ -1286,36 +739,19 @@ void audio_reset_session(void) { seq_and_bank_pool_init(&sSeqAndBankPoolSplit); sPersistentCommonPoolSplit.wantSeq = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem); sPersistentCommonPoolSplit.wantBank = DOUBLE_SIZE_ON_64_BIT(preset->persistentBankMem); -#if defined(VERSION_SH) || defined(VERSION_CN) sPersistentCommonPoolSplit.wantUnused = preset->unk18; -#else - sPersistentCommonPoolSplit.wantUnused = 0; -#endif persistent_pools_init(&sPersistentCommonPoolSplit); sTemporaryCommonPoolSplit.wantSeq = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem); sTemporaryCommonPoolSplit.wantBank = DOUBLE_SIZE_ON_64_BIT(preset->temporaryBankMem); -#if defined(VERSION_SH) || defined(VERSION_CN) sTemporaryCommonPoolSplit.wantUnused = preset->unk24; -#else - sTemporaryCommonPoolSplit.wantUnused = 0; -#endif temporary_pools_init(&sTemporaryCommonPoolSplit); -#if defined(VERSION_SH) || defined(VERSION_CN) unk_pools_init(preset->unkMem28, preset->unkMem2C); -#endif reset_bank_and_seq_load_status(); -#if defined(VERSION_JP) || defined(VERSION_US) - for (j = 0; j < 2; j++) { - gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64)); - } -#endif - gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * sizeof(struct Note)); note_init_all(); init_note_free_list(); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, (gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes) * sizeof(struct NoteSubEu)); for (j = 0; j != 2; j++) { @@ -1329,21 +765,14 @@ void audio_reset_session(void) { for (j = 0; j < gNumSynthesisReverbs; j++) { reverb = &gSynthesisReverbs[j]; reverbSettings = &preset->reverbSettings[j]; -#if defined(VERSION_SH) || defined(VERSION_CN) reverb->downsampleRate = reverbSettings->downsampleRate; reverb->windowSize = reverbSettings->windowSize * 64; reverb->windowSize /= reverb->downsampleRate; -#else - reverb->windowSize = reverbSettings->windowSize * 64; - reverb->downsampleRate = reverbSettings->downsampleRate; -#endif reverb->reverbGain = reverbSettings->gain; -#if defined(VERSION_SH) || defined(VERSION_CN) reverb->panRight = reverbSettings->unk4; reverb->panLeft = reverbSettings->unk6; reverb->unk5 = reverbSettings->unk8; reverb->unk08 = reverbSettings->unkA; -#endif reverb->useReverb = 8; reverb->ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2); reverb->ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2); @@ -1352,13 +781,8 @@ void audio_reset_session(void) { reverb->curFrame = 0; reverb->bufSizePerChannel = reverb->windowSize; reverb->framesLeftToIgnore = 2; -#if defined(VERSION_SH) || defined(VERSION_CN) reverb->resampleFlags = A_INIT; -#endif if (reverb->downsampleRate != 1) { -#if !defined(VERSION_SH) && !defined(VERSION_CN) - reverb->resampleFlags = A_INIT; -#endif reverb->resampleRate = 0x8000 / reverb->downsampleRate; reverb->resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); reverb->resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); @@ -1373,7 +797,6 @@ void audio_reset_session(void) { reverb->items[1][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); } } -#if defined(VERSION_SH) || defined(VERSION_CN) if (reverbSettings->unkC != 0) { reverb->unk108 = sound_alloc_uninitialized(&gNotesAndBuffersPool, 16 * sizeof(s16)); reverb->unk100 = sound_alloc_uninitialized(&gNotesAndBuffersPool, 8 * sizeof(s16)); @@ -1388,62 +811,16 @@ void audio_reset_session(void) { } else { reverb->unk104 = NULL; } -#endif } -#else - if (reverbWindowSize == 0) { - gSynthesisReverb.useReverb = 0; - } else { - gSynthesisReverb.useReverb = 8; - gSynthesisReverb.ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, reverbWindowSize * 2); - gSynthesisReverb.ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, reverbWindowSize * 2); - gSynthesisReverb.nextRingBufferPos = 0; - gSynthesisReverb.unkC = 0; - gSynthesisReverb.curFrame = 0; - gSynthesisReverb.bufSizePerChannel = reverbWindowSize; - gSynthesisReverb.reverbGain = preset->reverbGain; - gSynthesisReverb.framesLeftToIgnore = 2; - if (gReverbDownsampleRate != 1) { - gSynthesisReverb.resampleFlags = A_INIT; - gSynthesisReverb.resampleRate = 0x8000 / gReverbDownsampleRate; - gSynthesisReverb.resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); - gSynthesisReverb.resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); - gSynthesisReverb.unk24 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); - gSynthesisReverb.unk28 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); - for (i = 0; i < gAudioUpdatesPerFrame; i++) { - mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); - gSynthesisReverb.items[0][i].toDownsampleLeft = mem; - gSynthesisReverb.items[0][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); - mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); - gSynthesisReverb.items[1][i].toDownsampleLeft = mem; - gSynthesisReverb.items[1][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); - } - } - } -#endif - init_sample_dma_buffers(gMaxSimultaneousNotes); -#if defined(VERSION_EU) - build_vol_rampings_table(0, gAudioBufferParameters.samplesPerUpdate); -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) D_SH_8034F68C = 0; D_SH_803479B4 = 4096; -#endif osWritebackDCacheAll(); - -#if defined(VERSION_JP) || defined(VERSION_US) - if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { - gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; - } -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) void *unk_pool1_lookup(s32 poolIdx, s32 id) { s32 i; @@ -1570,11 +947,9 @@ struct UnkEntry *func_sh_802f1ec4(u32 size) { itemEnd = unkStruct->ramAddr + unkStruct->sample->size - 1; if (itemEnd < phi_s3 && itemStart < phi_s3) { continue; - } if (itemEnd >= temp_s2 && itemStart >= temp_s2) { continue; - } unkStruct->isFree = TRUE; @@ -1723,17 +1098,4 @@ void func_sh_802f23ec(void) { } } } -#endif -#ifdef VERSION_EU -u8 audioString22[] = "SFrame Sample %d %d %d\n"; -u8 audioString23[] = "AHPBASE %x\n"; -u8 audioString24[] = "AHPCUR %x\n"; -u8 audioString25[] = "HeapTop %x\n"; -u8 audioString26[] = "SynoutRate %d / %d \n"; -u8 audioString27[] = "FXSIZE %d\n"; -u8 audioString28[] = "FXCOMP %d\n"; -u8 audioString29[] = "FXDOWN %d\n"; -u8 audioString30[] = "WaveCacheLen: %d\n"; -u8 audioString31[] = "SpecChange Finished\n"; -#endif diff --git a/src/audio/heap.h b/src/audio/sh/heap.h similarity index 71% rename from src/audio/heap.h rename to src/audio/sh/heap.h index c3c36e67..a521b195 100644 --- a/src/audio/heap.h +++ b/src/audio/sh/heap.h @@ -25,12 +25,8 @@ struct SoundAllocPool { struct SeqOrBankEntry { u8 *ptr; u32 size; -#if defined(VERSION_SH) || defined(VERSION_CN) s16 poolIndex; s16 id; -#else - s32 id; // seqId or bankId -#endif }; // size = 0xC struct PersistentPool { @@ -40,20 +36,9 @@ struct PersistentPool { }; // size = 0x194 struct TemporaryPool { - /*EU, SH*/ - /*0x00, 0x00*/ u32 nextSide; - /*0x04, */ struct SoundAllocPool pool; - /*0x04, pool.start */ - /*0x08, pool.cur */ - /*0x0C, 0x0C pool.size */ - /*0x10, 0x10 pool.numAllocatedEntries */ - /*0x14, */ struct SeqOrBankEntry entries[2]; - /*0x14, 0x14 entries[0].ptr */ - /*0x18, entries[0].size*/ - /*0x1C, 0x1E entries[0].id */ - /*0x20, 0x20 entries[1].ptr */ - /*0x24, entries[1].size*/ - /*0x28, 0x2A entries[1].id */ + /*0x00*/ u32 nextSide; + /*0x04*/ struct SoundAllocPool pool; + /*0x14*/ struct SeqOrBankEntry entries[2]; }; // size = 0x2C struct SoundMultiPool { @@ -93,45 +78,30 @@ extern struct SoundAllocPool gPersistentCommonPool; extern struct SoundAllocPool gTemporaryCommonPool; extern struct SoundMultiPool gSeqLoadedPool; extern struct SoundMultiPool gBankLoadedPool; -#if defined(VERSION_SH) || defined(VERSION_CN) extern struct Unk1Pool gUnkPool1; extern struct UnkPool gUnkPool2; extern struct UnkPool gUnkPool3; -#endif extern u8 gBankLoadStatus[64]; extern u8 gSeqLoadStatus[256]; extern volatile u8 gAudioResetStatus; extern u8 gAudioResetPresetIdToLoad; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern volatile u8 gAudioResetStatus; -#endif void *soundAlloc(struct SoundAllocPool *pool, u32 size); void *sound_alloc_uninitialized(struct SoundAllocPool *pool, u32 size); void sound_init_main_pools(s32 sizeForAudioInitPool); void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size); -#if defined(VERSION_SH) || defined(VERSION_CN) void *alloc_bank_or_seq(s32 poolIdx, s32 size, s32 arg3, s32 id); void *get_bank_or_seq(s32 poolIdx, s32 arg1, s32 id); -#else -void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id); -void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id); -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 audio_shut_down_and_reset_step(void); void audio_reset_session(void); -#else -void audio_reset_session(struct AudioSessionSettings *preset); -#endif void discard_bank(s32 bankId); -#if defined(VERSION_SH) || defined(VERSION_CN) void fill_filter(s16 filter[8], s32 arg1, s32 arg2); u8 *func_sh_802f1d40(u32 size, s32 bank, u8 *arg2, s8 medium); u8 *func_sh_802f1d90(u32 size, s32 bank, u8 *arg2, s8 medium); void *unk_pool1_lookup(s32 poolIdx, s32 id); void *unk_pool1_alloc(s32 poolIndex, s32 arg1, u32 size); -#endif #endif // AUDIO_HEAP_H diff --git a/src/audio/sh/internal.h b/src/audio/sh/internal.h new file mode 100644 index 00000000..3cf4dd61 --- /dev/null +++ b/src/audio/sh/internal.h @@ -0,0 +1,597 @@ +#ifndef AUDIO_INTERNAL_H +#define AUDIO_INTERNAL_H + +#include + +#include "types.h" + +#define SEQUENCE_PLAYERS 4 +#define SEQUENCE_CHANNELS 48 +#define SEQUENCE_LAYERS 64 + +#define LAYERS_MAX 4 +#define CHANNELS_MAX 16 + +#define NO_LAYER ((struct SequenceChannelLayer *)(-1)) + +#define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts +#define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing +#define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half + +#define SEQUENCE_PLAYER_STATE_0 0 +#define SEQUENCE_PLAYER_STATE_FADE_OUT 1 +#define SEQUENCE_PLAYER_STATE_2 2 +#define SEQUENCE_PLAYER_STATE_3 3 +#define SEQUENCE_PLAYER_STATE_4 4 + +#define NOTE_PRIORITY_DISABLED 0 +#define NOTE_PRIORITY_STOPPING 1 +#define NOTE_PRIORITY_MIN 2 +#define NOTE_PRIORITY_DEFAULT 3 + +#define TATUMS_PER_BEAT 48 + +// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing +#define CODEC_ADPCM 0 +#define CODEC_S8 1 +#define CODEC_SKIP 2 + +#define TEMPO_SCALE TATUMS_PER_BEAT + +#define JP_DOUBLE(x) x ## f + +// Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion, +// resulting in more bloated codegen, while on later versions it goes through s32. +// Since u8 and u16 fit losslessly in both, behavior is the same. +#define FLOAT_CAST(x) (f32) (s32) (x) + +// No-op printf macro which leaves string literals in rodata in IDO. IDO +// doesn't support variadic macros, so instead we let the parameter list +// expand to a no-op comma expression. Another possibility is that it might +// have expanded to something with "if (0)". See also goddard/gd_main.h. +// On US/JP, -sopt optimizes away these except for external.c. +#ifdef __sgi +#define stubbed_printf +#else +#define stubbed_printf(...) +#endif + +#define eu_stubbed_printf_0(msg) +#define eu_stubbed_printf_1(msg, a) +#define eu_stubbed_printf_2(msg, a, b) +#define eu_stubbed_printf_3(msg, a, b, c) + +struct NotePool; + +struct AudioListItem { + // A node in a circularly linked list. Each node is either a head or an item: + // - Items can be either detached (prev = NULL), or attached to a list. + // 'value' points to something of interest. + // - List heads are always attached; if a list is empty, its head points + // to itself. 'count' contains the size of the list. + // If the list holds notes, 'pool' points back to the pool where it lives. + // Otherwise, that member is NULL. + struct AudioListItem *prev; + struct AudioListItem *next; + union { + void *value; // either Note* or SequenceChannelLayer* + s32 count; + } u; + struct NotePool *pool; +}; // size = 0x10 + +struct NotePool { + struct AudioListItem disabled; + struct AudioListItem decaying; + struct AudioListItem releasing; + struct AudioListItem active; +}; + +struct VibratoState { + /*0x00*/ struct SequenceChannel *seqChannel; + /*0x04*/ u32 time; + /*0x08*/ s16 *curve; + /*0x0C*/ f32 extent; + /*0x10*/ f32 rate; + /*0x14*/ u8 active; + /*0x16*/ u16 rateChangeTimer; + /*0x18*/ u16 extentChangeTimer; + /*0x1A*/ u16 delay; +}; // size = 0x1C + +// Pitch sliding by up to one octave in the positive direction. Negative +// direction is "supported" by setting extent to be negative. The code +// extrapolates exponentially in the wrong direction in that case, but that +// doesn't prevent seqplayer from doing it, AFAICT. +struct Portamento { + u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 + f32 cur; + f32 speed; + f32 extent; +}; // size = 0x10 + +struct AdsrEnvelope { + s16 delay; + s16 arg; +}; // size = 0x4 + +struct AdpcmLoop { + u32 start; + u32 end; + u32 count; + u32 pad; + s16 state[16]; // only exists if count != 0. 8-byte aligned +}; + +struct AdpcmBook { + s32 order; + s32 npredictors; + s16 book[1]; // size 8 * order * npredictors. 8-byte aligned +}; + +struct AudioBankSample { + /* 0x00 */ u32 codec : 4; + /* 0x00 */ u32 medium : 2; + /* 0x00 */ u32 bit1 : 1; + /* 0x00 */ u32 isPatched : 1; + /* 0x01 */ u32 size : 24; + u8 *sampleAddr; + struct AdpcmLoop *loop; + struct AdpcmBook *book; +}; + +struct AudioBankSound { + struct AudioBankSample *sample; + f32 tuning; // frequency scale factor +}; // size = 0x8 + +struct Instrument { + /*0x00*/ u8 loaded; + /*0x01*/ u8 normalRangeLo; + /*0x02*/ u8 normalRangeHi; + /*0x03*/ u8 releaseRate; + /*0x04*/ struct AdsrEnvelope *envelope; + /*0x08*/ struct AudioBankSound lowNotesSound; + /*0x10*/ struct AudioBankSound normalNotesSound; + /*0x18*/ struct AudioBankSound highNotesSound; +}; // size = 0x20 + +struct Drum { + u8 releaseRate; + u8 pan; + u8 loaded; + struct AudioBankSound sound; + struct AdsrEnvelope *envelope; +}; + +struct AudioBank { + struct Drum **drums; + struct Instrument *instruments[1]; +}; // dynamic size + +struct CtlEntry { + u8 numInstruments; + u8 numDrums; + u8 bankId1; + u8 bankId2; + struct Instrument **instruments; + struct Drum **drums; +}; // size = 0xC + +struct M64ScriptState { + u8 *pc; + u8 *stack[4]; + u8 remLoopIters[4]; + u8 depth; +}; // size = 0x1C + +// Also known as a Group, according to debug strings. +struct SequencePlayer { + /*0x000*/ u8 enabled : 1; + /*0x000*/ u8 finished : 1; // never read + /*0x000*/ u8 muted : 1; + /*0x000*/ u8 seqDmaInProgress : 1; + /*0x000*/ u8 bankDmaInProgress : 1; + /*0x000*/ u8 recalculateVolume : 1; + /*0x000*/ u8 unkSh: 1; + /*0x001*/ u8 state; + /*0x002*/ u8 noteAllocPolicy; + /*0x003*/ u8 muteBehavior; + /*0x004*/ u8 seqId; + /*0x005*/ u8 defaultBank[1]; // must be an array to get a comparison + // to match; other u8's might also be part of that array + /*0x006*/ u8 loadingBankId; + /*0x007*/ s8 seqVariationEu[1]; + /*0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU + /*0x00A*/ u16 tempoAcc; + /*0x00C*/ s16 tempoAdd; + /*0x00E*/ s16 transposition; + /*0x010*/ u16 delay; + /*0x012*/ u16 fadeRemainingFrames; + /*0x014*/ u16 fadeTimerUnkEu; + /*0x018*/ u8 *seqData; // buffer of some sort + /*0x01C*/ f32 fadeVolume; // set to 1.0f + /*0x020*/ f32 fadeVelocity; // set to 0.0f + /*0x024*/ f32 volume; // set to 0.0f + /*0x028*/ f32 muteVolumeScale; // set to 0.5f + /*0x02C*/ f32 fadeVolumeScale; + /*0x030*/ f32 appliedFadeVolume; + /*0x034*/ struct SequenceChannel *channels[CHANNELS_MAX]; + /*0x074*/ struct M64ScriptState scriptState; + /*0x090*/ u8 *shortNoteVelocityTable; + /*0x094*/ u8 *shortNoteDurationTable; + /*0x098*/ struct NotePool notePool; + /*0x0D8*/ OSMesgQueue seqDmaMesgQueue; + /*0x0F0*/ OSMesg seqDmaMesg; + /*0x0F4*/ OSIoMesg seqDmaIoMesg; + /*0x10C*/ OSMesgQueue bankDmaMesgQueue; + /*0x124*/ OSMesg bankDmaMesg; + /*0x128*/ OSIoMesg bankDmaIoMesg; + /*0x140*/ u8 *bankDmaCurrMemAddr; + /*0x144*/ uintptr_t bankDmaCurrDevAddr; + /*0x148*/ ssize_t bankDmaRemaining; +}; // size = 0x14C + +struct AdsrSettings { + u8 releaseRate; + u8 sustain; + struct AdsrEnvelope *envelope; +}; // size = 0x8 + +struct AdsrState { + /*0x00*/ u8 action; + /*0x01*/ u8 state; + /*0x02*/ s16 envIndex; + /*0x04*/ s16 delay; + /*0x08*/ f32 sustain; + /*0x0C*/ f32 velocity; + /*0x10*/ f32 fadeOutVel; + /*0x14*/ f32 current; + /*0x18*/ f32 target; + s32 pad1C; + /*0x20*/ struct AdsrEnvelope *envelope; +}; // size = 0x24 + +struct ReverbBitsData { + /* 0x00 */ u8 bit0 : 1; + /* 0x00 */ u8 bit1 : 1; + /* 0x00 */ u8 bit2 : 1; + /* 0x00 */ u8 usesHeadsetPanEffects : 1; + /* 0x00 */ u8 stereoHeadsetEffects : 2; + /* 0x00 */ u8 strongRight : 1; + /* 0x00 */ u8 strongLeft : 1; +}; + +union ReverbBits { + /* 0x00 */ struct ReverbBitsData s; + /* 0x00 */ u8 asByte; +}; +struct ReverbInfo { + u8 reverbVol; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + u8 pan; + union ReverbBits reverbBits; + f32 freqScale; + f32 velocity; + s32 unused; + s16 *filter; +}; + +struct NoteAttributes { + u8 reverbVol; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + u8 pan; + union ReverbBits reverbBits; + f32 freqScale; + f32 velocity; + s16 *filter; +}; // size = 0x10 + +// Also known as a SubTrack, according to debug strings. +// Confusingly, a SubTrack is a container of Tracks. +struct SequenceChannel { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 stopScript : 1; + /*0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething + /*0x00*/ u8 hasInstrument : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00*/ u8 largeNotes : 1; // notes specify duration and velocity + /*0x00*/ u8 unused : 1; // never read, set to 0 + /*0x01*/ union { + struct { + u8 freqScale : 1; + u8 volume : 1; + u8 pan : 1; + } as_bitfields; + u8 as_u8; + } changes; + /*0x02*/ u8 noteAllocPolicy; + /*0x03*/ u8 muteBehavior; + /*0x04*/ u8 reverbVol; // UQ0.8 + /*0x05*/ u8 notePriority; // 0-3 + /*0x06*/ u8 unkSH06; // some priority + /*0x07*/ u8 bankId; + /*0x08*/ u8 reverbIndex; + /*0x09*/ u8 bookOffset; + /*0x0A*/ u8 newPan; + /*0x0B*/ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128) + /*0x0C*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + /*0x0E*/ u16 vibratoRateStart; // initially 0x800 + /*0x10*/ u16 vibratoExtentStart; + /*0x12*/ u16 vibratoRateTarget; // initially 0x800 + /*0x14*/ u16 vibratoExtentTarget; + /*0x16*/ u16 vibratoRateChangeDelay; + /*0x18*/ u16 vibratoExtentChangeDelay; + /*0x1A*/ u16 vibratoDelay; + /*0x1C*/ u16 delay; + /*0x1E*/ s16 instOrWave; // either 0 (none), instrument index + 1, or + // 0x80..0x83 for sawtooth/triangle/sine/square waves. + /*0x20*/ s16 transposition; + /*0x24*/ f32 volumeScale; + /*0x28*/ f32 volume; + /*0x2C*/ s32 pan; + /*0x30*/ f32 appliedVolume; + /*0x34*/ f32 freqScale; + /*0x38*/ u8 (*dynTable)[][2]; + /*0x3C*/ struct Note *noteUnused; // never read + /*0x40*/ struct SequenceChannelLayer *layerUnused; // never read + /*0x44*/ struct Instrument *instrument; + /*0x48*/ struct SequencePlayer *seqPlayer; + /*0x4C*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; + /*0x64*/ struct M64ScriptState scriptState; + /*0x80*/ struct AdsrSettings adsr; + /*0x88*/ struct NotePool notePool; + /*0xC0*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, + // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment + /*0xC8*/ u16 unkC8; + /*0xCC*/ s16 *filter; +}; // size = 0xD0 + +// Also known as a Track, according to debug strings. +struct SequenceChannelLayer { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 stopSomething : 1; // ? + /*0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound + /*0x00*/ u8 unusedEu0b8 : 1; + /*0x00*/ u8 notePropertiesNeedInit : 1; + /*0x00*/ u8 ignoreDrumPan : 1; + /*0x01 */ union ReverbBits reverbBits; + /*0x02*/ u8 instOrWave; + /*0x03*/ u8 status; // 0x03 in SH + /*0x04*/ u8 noteDuration; // set to 0x80 + /*0x05*/ u8 portamentoTargetNote; + /*0x06*/ u8 pan; // 0..128 + /*0x07*/ u8 notePan; + /*0x08*/ struct Portamento portamento; + /*0x18*/ struct AdsrSettings adsr; + /*0x20*/ u16 portamentoTime; + /*0x22*/ s16 transposition; // #semitones added to play commands + // (m64 instruction encoding only allows referring to the limited range + // 0..0x3f; this makes 0x40..0x7f accessible as well) + /*0x24*/ f32 freqScale; + /*0x28*/ f32 freqScaleMultiplier; + /*0x2C*/ f32 velocitySquare; + /*0x30*/ f32 noteVelocity; + /*0x34*/ f32 noteFreqScale; + /*0x38*/ s16 shortNoteDefaultPlayPercentage; + /*0x3A*/ s16 playPercentage; // it's not really a percentage... + /*0x3C*/ s16 delay; + /*0x3E*/ s16 duration; + /*0x40*/ s16 delayUnused; // set to 'delay', never read + /*0x44*/ struct Note *note; + /*0x48*/ struct Instrument *instrument; + /*0x4C*/ struct AudioBankSound *sound; + /*0x50*/ struct SequenceChannel *seqChannel; + /*0x54*/ struct M64ScriptState scriptState; + /*0x70*/ struct AudioListItem listItem; +}; // size = 0x80 + +struct NoteSynthesisState { + /*0x00*/ u8 restart; + /*0x01*/ u8 sampleDmaIndex; + /*0x02*/ u8 prevHeadsetPanRight; + /*0x03*/ u8 prevHeadsetPanLeft; + /*0x04*/ u8 reverbVol; + /*0x05*/ u8 unk5; + /*0x06*/ u16 samplePosFrac; + /*0x08*/ s32 samplePosInt; + /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; + /*0x10*/ s16 curVolLeft; // Q1.15 + /*0x12*/ s16 curVolRight; // Q1.15 +}; +struct NotePlaybackState { + /*0x00*/ u8 priority; + /*0x01*/ u8 waveId; + /*0x02*/ u8 sampleCountIndex; + /*0x03*/ u8 bankId; + /*0x04*/ u8 unkSH34; + /*0x06*/ s16 adsrVolScale; + /*0x08*/ f32 portamentoFreqScale; + /*0x0C*/ f32 vibratoFreqScale; + /*0x10*/ struct SequenceChannelLayer *prevParentLayer; + /*0x14*/ struct SequenceChannelLayer *parentLayer; + /*0x18*/ struct SequenceChannelLayer *wantedParentLayer; + /*0x1C*/ struct NoteAttributes attributes; + /*0x2C*/ struct AdsrState adsr; + /*0x4C*/ struct Portamento portamento; + /*0x5C*/ struct VibratoState vibratoState; +}; +struct NoteSubEu { + /*0x00*/ volatile u8 enabled : 1; + /*0x00*/ u8 needsInit : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 envMixerNeedsInit : 1; + /*0x00*/ u8 stereoStrongRight : 1; + /*0x00*/ u8 stereoStrongLeft : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00*/ u8 usesHeadsetPanEffects : 1; + /*0x01*/ u8 reverbIndex : 3; + /*0x01*/ u8 bookOffset : 3; + /*0x01*/ u8 isSyntheticWave : 1; + /*0x01*/ u8 hasTwoAdpcmParts : 1; + /*0x02*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + /*0x03*/ u8 headsetPanRight; + /*0x04*/ u8 headsetPanLeft; + /*0x05*/ u8 reverbVol; // Q1.7 + /*0x06*/ u16 targetVolLeft; // UQ0.10 + /*0x08*/ u16 targetVolRight; // UQ0.10 + /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 + /*0x0C*/ union { + s16 *samples; + struct AudioBankSound *audioBankSound; + } sound; + /*0x10*/ s16 *filter; +}; +struct Note { + /*0x00*/ struct AudioListItem listItem; + /*0x10*/ struct NoteSynthesisState synthesisState; + // The next members are actually part of a struct (NotePlaybackState), but + // that resulted in messy US/EU ifdefs. Instead we cast to a struct pointer + // when needed... This breaks alignment on non-N64 platforms, which we hack + // around by skipping the padding in that case. + // TODO: re-introduce the struct +#ifdef TARGET_N64 + u8 pad0[12]; +#endif + + /*0x30*/ u8 priority; + /*0x31*/ u8 waveId; + /*0x32*/ u8 sampleCountIndex; + /*0x33*/ u8 bankId; + /*0x34*/ u8 unkSH34; + /*0x36*/ s16 adsrVolScale; + /*0x38*/ f32 portamentoFreqScale; + /*0x3C*/ f32 vibratoFreqScale; + /*0x40*/ struct SequenceChannelLayer *prevParentLayer; + /*0x44*/ struct SequenceChannelLayer *parentLayer; + /*0x48*/ struct SequenceChannelLayer *wantedParentLayer; + /*0x4C*/ struct NoteAttributes attributes; + /*0x5C*/ struct AdsrState adsr; + /*0x80*/ struct Portamento portamento; + /*0x90*/ struct VibratoState vibratoState; + u8 pad3[8]; + /*0xB4*/ struct NoteSubEu noteSubEu; +}; // size = 0xC8 + +struct NoteSynthesisBuffers { + s16 adpcmdecState[0x10]; + s16 finalResampleState[0x10]; + s16 unk[0x10]; + s16 filterBuffer[0x20]; + s16 panSamplesBuffer[0x20]; +}; + +struct ReverbSettingsEU { + u8 downsampleRate; // always 1 + u8 windowSize; // To be multiplied by 16 + u16 gain; + u16 unk4; // always zero + u16 unk6; // always zero + s8 unk8; // always -1 + u16 unkA; // always 0x3000 + s16 unkC; // always zero + s16 unkE; // always zero +}; + +struct AudioSessionSettingsEU { + /* 0x00 */ u32 frequency; + /* 0x04 */ u8 unk1; // always 1 + /* 0x05 */ u8 maxSimultaneousNotes; + /* 0x06 */ u8 numReverbs; // always 1 + /* 0x07 */ u8 unk2; // always 0 + /* 0x08 */ struct ReverbSettingsEU *reverbSettings; + /* 0x0C */ u16 volume; + /* 0x0E */ u16 unk3; // always 0 + /* 0x10 */ u32 persistentSeqMem; + /* 0x14 */ u32 persistentBankMem; + /* 0x18 */ u32 unk18; // always 0 + /* 0x1C */ u32 temporarySeqMem; + /* 0x20 */ u32 temporaryBankMem; + /* 0x24 */ u32 unk24; // always 0 + /* 0x28 */ u32 unkMem28; // always 0 + /* 0x2C */ u32 unkMem2C; // always 0 +}; // size = 0x30 + +struct AudioBufferParametersEU { + /*0x00*/ s16 presetUnk4; // audio frames per vsync? + /*0x02*/ u16 frequency; + /*0x04*/ u16 aiFrequency; // ?16 + /*0x06*/ s16 samplesPerFrameTarget; + /*0x08*/ s16 maxAiBufferLength; + /*0x0A*/ s16 minAiBufferLength; + /*0x0C*/ s16 updatesPerFrame; + /*0x0E*/ s16 samplesPerUpdate; + /*0x10*/ s16 samplesPerUpdateMax; + /*0x12*/ s16 samplesPerUpdateMin; + /*0x14*/ f32 resampleRate; // contains 32000.0f / frequency + /*0x18*/ f32 updatesPerFrameInv; // 1.0f / updatesPerFrame + /*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame) +}; + +struct EuAudioCmd { + union { +#if IS_BIG_ENDIAN + struct { + u8 op; + u8 arg1; + u8 arg2; + u8 arg3; + } s; +#else + struct { + u8 arg3; + u8 arg2; + u8 arg1; + u8 op; + } s; +#endif + s32 first; + } u; + union { + s32 as_s32; + u32 as_u32; + f32 as_f32; +#if IS_BIG_ENDIAN + u8 as_u8; + s8 as_s8; +#else + struct { + u8 pad0[3]; + u8 as_u8; + }; + struct { + u8 pad1[3]; + s8 as_s8; + }; +#endif + } u2; +}; + +struct PendingDmaSample { + u8 medium; + u8 bankId; + u8 idx; + uintptr_t devAddr; + void *vAddr; + u8 *resultSampleAddr; + s32 state; + s32 remaining; + s8 *io; + /*0x1C*/ struct AudioBankSample sample; + /*0x2C*/ OSMesgQueue queue; + /*0x44*/ OSMesg mesgs[1]; + /*0x48*/ OSIoMesg ioMesg; +}; + +struct UnkStruct80343D00 { + u32 someIndex; // array into one of the two slots below + struct PendingDmaSample arr[2]; +}; + +// in external.c +extern s32 D_SH_80343CF0; +extern struct UnkStruct80343D00 D_SH_80343D00; + +#endif // AUDIO_INTERNAL_H diff --git a/src/audio/load_sh.c b/src/audio/sh/load.c similarity index 99% rename from src/audio/load_sh.c rename to src/audio/sh/load.c index ac57be1f..360cd26d 100644 --- a/src/audio/load_sh.c +++ b/src/audio/sh/load.c @@ -1,9 +1,6 @@ -#if defined(VERSION_SH) || defined(VERSION_CN) #include -#include #include "data.h" -#include "external.h" #include "heap.h" #include "load.h" #include "seqplayer.h" @@ -447,7 +444,6 @@ void func_sh_802f3288(s32 idx) { continue; } - } } @@ -468,7 +464,6 @@ BAD_RETURN(s32) func_sh_802f3368(s32 bankId) { if (persistent->entries[i].id == bankId) { persistent->entries[i].id = -1; } - } discard_bank(bankId); @@ -558,7 +553,6 @@ void *func_sh_802f3598(s32 idx, s32 *medium) { *medium = f->seqArray[idx].medium; } return f->seqArray[idx].offset; - } void *func_sh_802f3688(s32 bankId) { @@ -768,7 +762,6 @@ void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *pat drum->envelope = BASE_OFFSET(patched, mem); drum->loaded = 1; } - } } } @@ -905,7 +898,6 @@ void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue * return 0; } break; - } vAddr = get_bank_or_seq_wrapper(poolIdx, idx); if (vAddr != NULL) { @@ -1622,7 +1614,6 @@ s32 func_sh_802f5948(s32 bankId, struct AudioBankSample *list[]) { inst = get_instrument_inner(bankId, i); if (inst == NULL) { continue; - } if (inst->normalRangeLo != 0) { numLoaded = func_sh_802f5900(inst->lowNotesSound.sample, numLoaded, list); @@ -1634,4 +1625,3 @@ s32 func_sh_802f5948(s32 bankId, struct AudioBankSample *list[]) { } return numLoaded; } -#endif diff --git a/src/audio/load.h b/src/audio/sh/load.h similarity index 82% rename from src/audio/load.h rename to src/audio/sh/load.h index 11e05546..29bf6bc4 100644 --- a/src/audio/load.h +++ b/src/audio/sh/load.h @@ -36,14 +36,10 @@ extern ALSeqFile *gSeqFileHeader; extern u8 *gAlBankSets; extern struct CtlEntry *gCtlEntries; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern struct AudioBufferParametersEU gAudioBufferParameters; -#endif extern s32 gAiFrequency; -#if defined(VERSION_SH) || defined(VERSION_CN) extern s16 gCurrAiBufferLength; extern s32 D_SH_8034F68C; -#endif extern s32 gMaxAudioCmds; extern s32 gMaxSimultaneousNotes; @@ -53,7 +49,6 @@ extern s16 gTempoInternalToExternal; extern s8 gAudioUpdatesPerFrame; // = 4 extern s8 gSoundMode; -#if defined(VERSION_SH) || defined(VERSION_CN) extern OSMesgQueue gUnkQueue1; struct UnkStructSH8034EC88 { @@ -74,29 +69,15 @@ struct PatchStruct { }; extern struct UnkStructSH8034EC88 D_SH_8034EC88[0x80]; -#endif void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg); void decrease_sample_dma_ttls(void); -#if defined(VERSION_SH) || defined(VERSION_CN) void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef, s32 medium); -#else -void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef); -#endif void init_sample_dma_buffers(s32 arg0); -#if defined(VERSION_SH) || defined(VERSION_CN) void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo); -#else -void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums); -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) void preload_sequence(u32 seqId, s32 preloadMask); -#else -void preload_sequence(u32 seqId, u8 preloadMask); -#endif void load_sequence(u32 player, u32 seqId, s32 loadAsync); -#if defined(VERSION_SH) || defined(VERSION_CN) void func_sh_802f3158(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue *retQueue); u8 *func_sh_802f3220(u32 seqId, u32 *a1); struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx); @@ -109,6 +90,4 @@ s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2); void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3); void func_sh_802f3288(s32 idx); -#endif - #endif // AUDIO_LOAD_H diff --git a/src/audio/playback.c b/src/audio/sh/playback.c similarity index 58% rename from src/audio/playback.c rename to src/audio/sh/playback.c index 333d0840..e39d09df 100644 --- a/src/audio/playback.c +++ b/src/audio/sh/playback.c @@ -7,50 +7,33 @@ #include "playback.h" #include "synthesis.h" #include "effects.h" -#include "external.h" +#include "../external.h" void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#if defined(VERSION_SH) || defined(VERSION_CN) void note_set_vel_pan_reverb(struct Note *note, struct ReverbInfo *reverbInfo) -#else -void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol) -#endif { struct NoteSubEu *sub = ¬e->noteSubEu; f32 volRight, volLeft; u8 strongRight; u8 strongLeft; s32 smallPanIndex; -#ifdef VERSION_EU - u16 unkMask = ~0x80; -#else UNUSED u32 pad; UNUSED u32 pad1; f32 velocity; u8 pan; u8 reverbVol; struct ReverbBitsData reverbBits; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) note_set_resampling_rate(note, reverbInfo->freqScale); velocity = reverbInfo->velocity; pan = reverbInfo->pan; reverbVol = reverbInfo->reverbVol; reverbBits = reverbInfo->reverbBits.s; pan &= 0x7f; -#else - pan &= unkMask; -#endif if (note->noteSubEu.stereoHeadsetEffects && gSoundMode == SOUND_MODE_HEADSET) { -#if defined(VERSION_SH) || defined(VERSION_CN) smallPanIndex = pan >> 1; -#else - smallPanIndex = pan >> 3; -#endif if (smallPanIndex >= ARRAY_COUNT(gHeadsetPanQuantization)) { smallPanIndex = ARRAY_COUNT(gHeadsetPanQuantization) - 1; } @@ -64,17 +47,10 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbV volLeft = gHeadsetPanVolume[pan]; volRight = gHeadsetPanVolume[127 - pan]; } else if (sub->stereoHeadsetEffects && gSoundMode == SOUND_MODE_STEREO) { -#if defined(VERSION_SH) || defined(VERSION_CN) strongRight = FALSE; strongLeft = FALSE; sub->headsetPanRight = 0; sub->headsetPanLeft = 0; -#else - strongLeft = FALSE; - strongRight = FALSE; - sub->headsetPanLeft = 0; - sub->headsetPanRight = 0; -#endif sub->usesHeadsetPanEffects = FALSE; @@ -89,7 +65,6 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbV sub->stereoStrongRight = strongRight; sub->stereoStrongLeft = strongLeft; -#if defined(VERSION_SH) || defined(VERSION_CN) switch (reverbBits.stereoHeadsetEffects) { case 0: sub->stereoStrongRight = reverbBits.strongRight; @@ -109,7 +84,6 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbV sub->stereoStrongLeft = reverbBits.strongLeft ^ strongLeft; break; } -#endif } else if (gSoundMode == SOUND_MODE_MONO) { volLeft = 0.707f; volRight = 0.707f; @@ -118,7 +92,6 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbV volRight = gDefaultPanVolume[127 - pan]; } -#if defined(VERSION_SH) || defined(VERSION_CN) if (velocity < 0.0f) { velocity = 0.0f; } @@ -130,27 +103,10 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbV sub->targetVolRight = ((s32) (velocity * volRight * 4095.999f)); sub->synthesisVolume = reverbInfo->synthesisVolume; sub->filter = reverbInfo->filter; -#else - if (velocity < 0.0f) { - stubbed_printf("Audio: setvol: volume minus %f\n", velocity); - velocity = 0.0f; - } - if (velocity > 32767.f) { - stubbed_printf("Audio: setvol: volume overflow %f\n", velocity); - velocity = 32767.f; - } - - sub->targetVolLeft = ((s32) (velocity * volLeft) & 0xffff) >> 5; - sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5; -#endif //! @bug for the change to UQ0.7, the if statement should also have been changed accordingly if (sub->reverbVol != reverbVol) { -#if defined(VERSION_SH) || defined(VERSION_CN) sub->reverbVol = reverbVol >> 1; -#else - sub->reverbVol = reverbVol; -#endif sub->envMixerNeedsInit = TRUE; return; } @@ -162,22 +118,12 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbV } } -#if defined(VERSION_SH) || defined(VERSION_CN) #define MIN_RESAMPLING_RATE 1.99998f -#else -#define MIN_RESAMPLING_RATE 1.99996f -#endif void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) { f32 resamplingRate = 0.0f; struct NoteSubEu *tempSub = ¬e->noteSubEu; -#ifdef VERSION_EU - if (resamplingRateInput < 0.0f) { - stubbed_printf("Audio: setpitch: pitch minus %f\n", resamplingRateInput); - resamplingRateInput = 0.0f; - } -#endif if (resamplingRateInput < 2.0f) { tempSub->hasTwoAdpcmParts = 0; @@ -198,100 +144,7 @@ void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) { note->noteSubEu.resamplingRateFixedPoint = (s32) (resamplingRate * 32768.0f); } -#ifdef VERSION_EU -struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone) { - struct AudioBankSound *sound; - if (semitone < instrument->normalRangeLo) { - sound = &instrument->lowNotesSound; - } else if (semitone <= instrument->normalRangeHi) { - sound = &instrument->normalNotesSound; - } else { - sound = &instrument->highNotesSound; - } - return sound; -} - -struct Instrument *get_instrument_inner(s32 bankId, s32 instId) { - struct Instrument *inst; - - if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { - stubbed_printf("Audio: voiceman: No bank error %d\n", bankId); - gAudioErrorFlags = bankId + 0x10000000; - return NULL; - } - - if (instId >= gCtlEntries[bankId].numInstruments) { - stubbed_printf("Audio: voiceman: progNo. overflow %d,%d\n", - instId, gCtlEntries[bankId].numInstruments); - gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000; - return NULL; - } - - inst = gCtlEntries[bankId].instruments[instId]; - if (inst == NULL) { - stubbed_printf("Audio: voiceman: progNo. undefined %d,%d\n", bankId, instId); - gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000; - return inst; - } - -#ifdef VERSION_EU - if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst - && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start - + gBankLoadedPool.persistent.pool.size)) - || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst - && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start - + gBankLoadedPool.temporary.pool.size))) { - return inst; - } - - stubbed_printf("Audio: voiceman: BAD Voicepointer %x,%d,%d\n", inst, bankId, instId); - gAudioErrorFlags = ((bankId << 8) + instId) + 0x2000000; - return NULL; -#else - return inst; -#endif -} - -struct Drum *get_drum(s32 bankId, s32 drumId) { - struct Drum *drum; - -#if defined(VERSION_SH) || defined(VERSION_CN) - if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { - stubbed_printf("Audio: voiceman: No bank error %d\n", bankId); - gAudioErrorFlags = bankId + 0x10000000; - return NULL; - } -#endif - - if (drumId >= gCtlEntries[bankId].numDrums) { - stubbed_printf("Audio: voiceman: Percussion Overflow %d,%d\n", - drumId, gCtlEntries[bankId].numDrums); - gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000; - return NULL; - } - -#ifndef NO_SEGMENTED_MEMORY - if ((uintptr_t) gCtlEntries[bankId].drums < 0x80000000U) { - stubbed_printf("Percussion Pointer Error\n"); - return NULL; - } -#endif - - drum = gCtlEntries[bankId].drums[drumId]; - if (drum == NULL) { - stubbed_printf("Audio: voiceman: Percpointer NULL %d,%d\n", bankId, drumId); - gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000; - } - return drum; -} -#endif -#endif // VERSION_EU - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); -#else -s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); -#endif void note_init(struct Note *note) { if (note->parentLayer->adsr.releaseRate == 0) { @@ -299,80 +152,35 @@ void note_init(struct Note *note) { } else { adsr_init(¬e->adsr, note->parentLayer->adsr.envelope, ¬e->adsrVolScale); } -#if defined(VERSION_SH) || defined(VERSION_CN) note->unkSH34 = 0; -#endif note->adsr.state = ADSR_STATE_INITIAL; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note->noteSubEu = gDefaultNoteSub; -#else - note_init_volume(note); - note_enable(note); -#endif } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) #define note_disable2 note_disable void note_disable(struct Note *note) { if (note->noteSubEu.needsInit == TRUE) { note->noteSubEu.needsInit = FALSE; } -#ifdef VERSION_EU - else { - note_set_vel_pan_reverb(note, 0, 0x40, 0); - } -#endif note->priority = NOTE_PRIORITY_DISABLED; -#if defined(VERSION_SH) || defined(VERSION_CN) note->unkSH34 = 0; -#endif note->parentLayer = NO_LAYER; note->prevParentLayer = NO_LAYER; note->noteSubEu.enabled = FALSE; note->noteSubEu.finished = FALSE; -#if defined(VERSION_SH) || defined(VERSION_CN) note->adsr.state = ADSR_STATE_DISABLED; note->adsr.current = 0; -#endif } -#else -void note_disable2(struct Note *note) { - note_disable(note); -} -#endif // VERSION_EU || VERSION_SH void process_notes(void) { f32 scale; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - f32 frequency; -#if defined(VERSION_JP) || defined(VERSION_US) - u8 reverbVol; -#endif - f32 velocity; -#if defined(VERSION_JP) || defined(VERSION_US) - f32 pan; - f32 cap; -#endif -#endif struct Note *note; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) struct NotePlaybackState *playbackState; struct NoteSubEu *noteSubEu; -#ifdef VERSION_EU - UNUSED u8 pad[12]; - u8 reverbVol; - UNUSED u8 pad3; - u8 pan; -#else UNUSED u8 pad[8]; struct ReverbInfo reverbInfo; -#endif u8 bookOffset; -#endif struct NoteAttributes *attributes; -#if defined(VERSION_JP) || defined(VERSION_US) - struct AudioListItem *it; -#endif s32 i; // Macro versions of audio_list_push_front and audio_list_remove. @@ -389,7 +197,6 @@ void process_notes(void) { for (i = 0; i < gMaxSimultaneousNotes; i++) { note = &gNotes[i]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) playbackState = (struct NotePlaybackState *) ¬e->priority; if (note->parentLayer != NO_LAYER) { #ifndef NO_SEGMENTED_MEMORY @@ -397,7 +204,6 @@ void process_notes(void) { continue; } #endif -#if defined(VERSION_SH) || defined(VERSION_CN) if (note != playbackState->parentLayer->note && playbackState->unkSH34 == 0) { playbackState->adsr.action |= ADSR_ACTION_RELEASE; playbackState->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; @@ -428,43 +234,11 @@ void process_notes(void) { } else if (playbackState->unkSH34 == 0 && playbackState->priority >= 1) { continue; } -#else - if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) { - goto c; - } else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) { - eu_stubbed_printf_0("CAUTION:SUB IS SEPARATED FROM GROUP"); - sequence_channel_disable(playbackState->parentLayer->seqChannel); - playbackState->priority = NOTE_PRIORITY_STOPPING; - continue; - } else if (playbackState->parentLayer->seqChannel->seqPlayer->muted) { - if ((playbackState->parentLayer->seqChannel->muteBehavior - & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES))) { - goto c; - } - } - goto d; - if (1) { - c: - seq_channel_layer_note_release(playbackState->parentLayer); - audio_list_remove(¬e->listItem); - audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); - playbackState->priority = NOTE_PRIORITY_STOPPING; - } - } else if (playbackState->priority >= NOTE_PRIORITY_MIN) { - continue; - } -#endif d: if (playbackState->priority != NOTE_PRIORITY_DISABLED) { -#if defined(VERSION_SH) || defined(VERSION_CN) if (1) {} -#endif noteSubEu = ¬e->noteSubEu; -#if defined(VERSION_SH) || defined(VERSION_CN) if (playbackState->unkSH34 >= 1 || noteSubEu->finished) { -#else - if (playbackState->priority == NOTE_PRIORITY_STOPPING || noteSubEu->finished) { -#endif if (playbackState->adsr.state == ADSR_STATE_DISABLED || noteSubEu->finished) { if (playbackState->wantedParentLayer != NO_LAYER) { note_disable(note); @@ -490,10 +264,6 @@ void process_notes(void) { goto skip; } } -#if !defined(VERSION_SH) && !defined(VERSION_CN) - if (1) { - } -#endif } else if (playbackState->adsr.state == ADSR_STATE_DISABLED) { note_disable(note); audio_list_remove(¬e->listItem); @@ -504,7 +274,6 @@ void process_notes(void) { scale = adsr_update(&playbackState->adsr); note_vibrato_update(note); attributes = &playbackState->attributes; -#if defined(VERSION_SH) || defined(VERSION_CN) if (playbackState->unkSH34 == 1 || playbackState->unkSH34 == 2) { reverbInfo.freqScale = attributes->freqScale; reverbInfo.velocity = attributes->velocity; @@ -534,104 +303,14 @@ void process_notes(void) { reverbInfo.freqScale *= gAudioBufferParameters.resampleRate; reverbInfo.velocity *= scale; note_set_vel_pan_reverb(note, &reverbInfo); -#else - if (playbackState->priority == NOTE_PRIORITY_STOPPING) { - frequency = attributes->freqScale; - velocity = attributes->velocity; - pan = attributes->pan; - reverbVol = attributes->reverbVol; - if (1) { - } - bookOffset = noteSubEu->bookOffset; - } else { - frequency = playbackState->parentLayer->noteFreqScale; - velocity = playbackState->parentLayer->noteVelocity; - pan = playbackState->parentLayer->notePan; - reverbVol = playbackState->parentLayer->seqChannel->reverbVol; - bookOffset = playbackState->parentLayer->seqChannel->bookOffset & 0x7; - } - - frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; - frequency *= gAudioBufferParameters.resampleRate; - velocity = velocity * scale * scale; - note_set_resampling_rate(note, frequency); - note_set_vel_pan_reverb(note, velocity, pan, reverbVol); -#endif noteSubEu->bookOffset = bookOffset; skip:; } -#else - if (note->priority != NOTE_PRIORITY_DISABLED) { - if (note->priority == NOTE_PRIORITY_STOPPING || note->finished) { - if (note->adsrVolScale == 0 || note->finished) { - if (note->wantedParentLayer != NO_LAYER) { - note_disable2(note); - if (note->wantedParentLayer->seqChannel != NULL) { - if (note_init_for_layer(note, note->wantedParentLayer) == TRUE) { - note_disable2(note); - POP(¬e->listItem); - PREPEND(¬e->listItem, &gNoteFreeLists.disabled); - } else { - note_vibrato_init(note); - audio_list_push_back(¬e->listItem.pool->active, - POP(¬e->listItem)); - note->wantedParentLayer = NO_LAYER; - } - } else { - note_disable2(note); - audio_list_push_back(¬e->listItem.pool->disabled, POP(¬e->listItem)); - note->wantedParentLayer = NO_LAYER; - continue; - } - } else { - note_disable2(note); - audio_list_push_back(¬e->listItem.pool->disabled, POP(¬e->listItem)); - continue; - } - } - } else { - if (note->adsr.state == ADSR_STATE_DISABLED) { - note_disable2(note); - audio_list_push_back(¬e->listItem.pool->disabled, POP(¬e->listItem)); - continue; - } - } - - adsr_update(¬e->adsr); - note_vibrato_update(note); - attributes = ¬e->attributes; - if (note->priority == NOTE_PRIORITY_STOPPING) { - frequency = attributes->freqScale; - velocity = attributes->velocity; - pan = attributes->pan; - reverbVol = attributes->reverbVol; - } else { - frequency = note->parentLayer->noteFreqScale; - velocity = note->parentLayer->noteVelocity; - pan = note->parentLayer->notePan; - reverbVol = note->parentLayer->seqChannel->reverbVol; - } - - scale = note->adsrVolScale; - frequency *= note->vibratoFreqScale * note->portamentoFreqScale; - cap = 3.99992f; - if (gAiFrequency != 32006) { - frequency *= US_FLOAT(32000.0) / (f32) gAiFrequency; - } - frequency = (frequency < cap ? frequency : cap); - scale *= 4.3498e-5f; // ~1 / 23000 - velocity = velocity * scale * scale; - note_set_frequency(note, frequency); - note_set_vel_pan_reverb(note, velocity, pan, reverbVol); - continue; - } -#endif } #undef PREPEND #undef POP } -#if defined(VERSION_SH) || defined(VERSION_CN) // These three are matching but have been moved from above in shindou: struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone) { struct AudioBankSound *sound; @@ -691,7 +370,6 @@ struct Drum *get_drum(s32 bankId, s32 drumId) { } return drum; } -#endif void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLayer, s32 target) { struct Note *note; @@ -701,9 +379,7 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa return; } -#if defined(VERSION_SH) || defined(VERSION_CN) seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; -#endif if (seqLayer->note == NULL) { return; @@ -712,19 +388,12 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa note = seqLayer->note; attributes = ¬e->attributes; -#if defined(VERSION_JP) || defined(VERSION_US) - if (seqLayer->seqChannel != NULL && seqLayer->seqChannel->noteAllocPolicy == 0) { - seqLayer->note = NULL; - } -#endif - if (note->wantedParentLayer == seqLayer) { note->wantedParentLayer = NO_LAYER; } if (note->parentLayer != seqLayer) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER && note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) { // Just guessing that this printf goes here... it's hard to parse. @@ -732,70 +401,41 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; note->adsr.action |= ADSR_ACTION_RELEASE; } -#endif return; } -#if !defined(VERSION_SH) && !defined(VERSION_CN) - seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; -#endif if (note->adsr.state != ADSR_STATE_DECAY) { attributes->freqScale = seqLayer->noteFreqScale; attributes->velocity = seqLayer->noteVelocity; attributes->pan = seqLayer->notePan; -#if defined(VERSION_SH) || defined(VERSION_CN) attributes->reverbBits = seqLayer->reverbBits; -#endif if (seqLayer->seqChannel != NULL) { attributes->reverbVol = seqLayer->seqChannel->reverbVol; -#if defined(VERSION_SH) || defined(VERSION_CN) attributes->synthesisVolume = seqLayer->seqChannel->synthesisVolume; attributes->filter = seqLayer->seqChannel->filter; if (seqLayer->seqChannel->seqPlayer->muted && (seqLayer->seqChannel->muteBehavior & 8) != 0) { note->noteSubEu.finished = TRUE; } note->priority = seqLayer->seqChannel->unkSH06; -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) else { -#endif note->priority = NOTE_PRIORITY_STOPPING; -#if defined(VERSION_SH) || defined(VERSION_CN) } -#endif note->prevParentLayer = note->parentLayer; note->parentLayer = NO_LAYER; if (target == ADSR_STATE_RELEASE) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; -#else - note->adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; -#endif note->adsr.action |= ADSR_ACTION_RELEASE; -#if defined(VERSION_SH) || defined(VERSION_CN) note->unkSH34 = 2; -#endif } else { -#if defined(VERSION_SH) || defined(VERSION_CN) note->unkSH34 = 1; -#endif note->adsr.action |= ADSR_ACTION_DECAY; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (seqLayer->adsr.releaseRate == 0) { note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; } else { note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; } note->adsr.sustain = (FLOAT_CAST(seqLayer->seqChannel->adsr.sustain) * note->adsr.current) / 256.0f; -#else - if (seqLayer->adsr.releaseRate == 0) { - note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * 24; - } else { - note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * 24; - } - note->adsr.sustain = (note->adsr.current * seqLayer->seqChannel->adsr.sustain) / 0x10000; -#endif } } @@ -813,16 +453,12 @@ void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer) { seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_RELEASE); } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer, s32 waveId) { f32 freqScale; f32 ratio; u8 sampleCountIndex; if (waveId < 128) { -#ifdef VERSION_EU - stubbed_printf("Audio:Wavemem: Bad voiceno (%d)\n", waveId); -#endif waveId = 128; } @@ -852,65 +488,7 @@ s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye return sampleCountIndex; } -#else -void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { - s32 i; - s32 j; - s32 pos; - s32 stepSize; - s32 offset; - u8 lim; - u8 origSampleCount = note->sampleCount; - - if (seqLayer->freqScale < US_FLOAT(1.0)) { - note->sampleCount = 64; - seqLayer->freqScale *= US_FLOAT(1.0465); - stepSize = 1; - } else if (seqLayer->freqScale < US_FLOAT(2.0)) { - note->sampleCount = 32; - seqLayer->freqScale *= US_FLOAT(0.52325); - stepSize = 2; - } else if (seqLayer->freqScale < US_FLOAT(4.0)) { - note->sampleCount = 16; - seqLayer->freqScale *= US_FLOAT(0.26263); - stepSize = 4; - } else { - note->sampleCount = 8; - seqLayer->freqScale *= US_FLOAT(0.13081); - stepSize = 8; - } - - if (note->sampleCount == origSampleCount && seqLayer->seqChannel->instOrWave == note->instOrWave) { - return; - } - - // Load wave sample - note->instOrWave = (u8) seqLayer->seqChannel->instOrWave; - for (i = -1, pos = 0; pos < 0x40; pos += stepSize) { - i++; - note->synthesisBuffers->samples[i] = gWaveSamples[seqLayer->seqChannel->instOrWave - 0x80][pos]; - } - - // Repeat sample - for (offset = note->sampleCount; offset < 0x40; offset += note->sampleCount) { - lim = note->sampleCount; - if (offset < 0 || offset > 0) { - for (j = 0; j < lim; j++) { - note->synthesisBuffers->samples[offset + j] = note->synthesisBuffers->samples[j]; - } - } else { - for (j = 0; j < lim; j++) { - note->synthesisBuffers->samples[offset + j] = note->synthesisBuffers->samples[j]; - } - } - } - - osWritebackDCache(note->synthesisBuffers->samples, sizeof(note->synthesisBuffers->samples)); -} -#endif - void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 sampleCountIndex; s32 waveSampleCountIndex; s32 waveId = seqLayer->instOrWave; @@ -919,20 +497,7 @@ void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye } sampleCountIndex = note->sampleCountIndex; waveSampleCountIndex = build_synthetic_wave(note, seqLayer, waveId); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note->synthesisState.samplePosInt = note->synthesisState.samplePosInt * euUnknownData_8030194c[waveSampleCountIndex] / euUnknownData_8030194c[sampleCountIndex]; -#else // Not a real change. Just temporary so I can remove this variable. - note->synthesisState.samplePosInt = note->synthesisState.samplePosInt * gDefaultShortNoteVelocityTable[waveSampleCountIndex] / gDefaultShortNoteVelocityTable[sampleCountIndex]; -#endif -#else - s32 sampleCount = note->sampleCount; - build_synthetic_wave(note, seqLayer); - if (sampleCount != 0) { - note->samplePosInt *= note->sampleCount / sampleCount; - } else { - note->samplePosInt = 0; - } -#endif } void init_note_list(struct AudioListItem *list) { @@ -968,7 +533,6 @@ void note_pool_clear(struct NotePool *pool) { struct AudioListItem *source; struct AudioListItem *cur; struct AudioListItem *dest; - UNUSED s32 j; // unused in EU for (i = 0; i < 4; i++) { switch (i) { @@ -993,7 +557,6 @@ void note_pool_clear(struct NotePool *pool) { break; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) for (;;) { cur = source->next; if (cur == source) { @@ -1006,18 +569,6 @@ void note_pool_clear(struct NotePool *pool) { audio_list_remove(cur); audio_list_push_back(dest, cur); } -#else - j = 0; - do { - cur = source->next; - if (cur == source) { - break; - } - audio_list_remove(cur); - audio_list_push_back(dest, cur); - j++; - } while (j <= gMaxSimultaneousNotes); -#endif } } @@ -1108,7 +659,6 @@ struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) { } } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (best == NULL) { return NULL; } @@ -1116,19 +666,10 @@ struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) { if (limit <= ((struct Note *) best->u.value)->priority) { return NULL; } -#else - if (limit < ((struct Note *) best->u.value)->priority) { - return NULL; - } -#endif -#if !defined(VERSION_SH) && !defined(VERSION_CN) - audio_list_remove(best); -#endif return best->u.value; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { UNUSED s32 pad[4]; s16 instId; @@ -1159,37 +700,10 @@ void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLaye if (sub->isSyntheticWave) { build_synthetic_wave(note, seqLayer, instId); } -#if defined(VERSION_SH) || defined(VERSION_CN) note->bankId = seqLayer->seqChannel->bankId; -#else - sub->bankId = seqLayer->seqChannel->bankId; -#endif sub->stereoHeadsetEffects = seqLayer->seqChannel->stereoHeadsetEffects; sub->reverbIndex = seqLayer->seqChannel->reverbIndex & 3; } -#else -s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { - note->prevParentLayer = NO_LAYER; - note->parentLayer = seqLayer; - note->priority = seqLayer->seqChannel->notePriority; - if (IS_BANK_LOAD_COMPLETE(seqLayer->seqChannel->bankId) == FALSE) { - return TRUE; - } - - note->bankId = seqLayer->seqChannel->bankId; - note->stereoHeadsetEffects = seqLayer->seqChannel->stereoHeadsetEffects; - note->sound = seqLayer->sound; - seqLayer->status = SOUND_LOAD_STATUS_DISCARDABLE; // "loaded" - seqLayer->note = note; - seqLayer->seqChannel->noteUnused = note; - seqLayer->seqChannel->layerUnused = seqLayer; - if (note->sound == NULL) { - build_synthetic_wave(note, seqLayer); - } - note_init(note); - return FALSE; -} -#endif void func_80319728(struct Note *note, struct SequenceChannelLayer *seqLayer) { seq_channel_layer_note_release(note->parentLayer); @@ -1198,31 +712,16 @@ void func_80319728(struct Note *note, struct SequenceChannelLayer *seqLayer) { void note_release_and_take_ownership(struct Note *note, struct SequenceChannelLayer *seqLayer) { note->wantedParentLayer = seqLayer; -#if defined(VERSION_SH) || defined(VERSION_CN) note->priority = seqLayer->seqChannel->notePriority; -#else - note->priority = NOTE_PRIORITY_STOPPING; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; -#else - note->adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; -#endif note->adsr.action |= ADSR_ACTION_RELEASE; } struct Note *alloc_note_from_disabled(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { struct Note *note = audio_list_pop_back(&pool->disabled); if (note != NULL) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note_init_for_layer(note, seqLayer); -#else - if (note_init_for_layer(note, seqLayer) == TRUE) { - audio_list_push_front(&gNoteFreeLists.disabled, ¬e->listItem); - return NULL; - } -#endif audio_list_push_front(&pool->active, ¬e->listItem); } return note; @@ -1238,11 +737,8 @@ struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChan } struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { -#if defined(VERSION_SH) || defined(VERSION_CN) struct Note *rNote; -#endif struct Note *aNote; -#if defined(VERSION_SH) || defined(VERSION_CN) s32 rPriority, aPriority; rPriority = aPriority = 0x10; @@ -1251,22 +747,15 @@ struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChanne if (rNote != NULL) { rPriority = rNote->priority; } -#endif aNote = pop_node_with_lower_prio(&pool->active, seqLayer->seqChannel->notePriority); if (aNote == NULL) { eu_stubbed_printf_0("Audio: C-Alloc : lowerPrio is NULL\n"); } else { -#if defined(VERSION_SH) || defined(VERSION_CN) aPriority = aNote->priority; -#else - func_80319728(aNote, seqLayer); - audio_list_push_back(&pool->releasing, &aNote->listItem); -#endif } -#if defined(VERSION_SH) || defined(VERSION_CN) if (rNote == NULL && aNote == NULL) { return NULL; } @@ -1281,9 +770,6 @@ struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChanne rNote->wantedParentLayer = seqLayer; rNote->priority = seqLayer->seqChannel->notePriority; return rNote; -#else - return aNote; -#endif } struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { @@ -1293,17 +779,11 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { if (policy & NOTE_ALLOC_LAYER) { ret = seqLayer->note; if (ret != NULL && ret->prevParentLayer == seqLayer -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) && ret->wantedParentLayer == NO_LAYER -#endif ) { note_release_and_take_ownership(ret, seqLayer); audio_list_remove(&ret->listItem); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) audio_list_push_back(&ret->listItem.pool->releasing, &ret->listItem); -#else - audio_list_push_back(&gNoteFreeLists.releasing, &ret->listItem); -#endif return ret; } } @@ -1312,13 +792,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) { -#if defined(VERSION_SH) || defined(VERSION_CN) goto null_return; -#else - eu_stubbed_printf_0("Sub Limited Warning: Drop Voice"); - seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; - return NULL; -#endif } return ret; } @@ -1330,13 +804,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) { -#if defined(VERSION_SH) || defined(VERSION_CN) goto null_return; -#else - eu_stubbed_printf_0("Warning: Drop Voice"); - seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; - return NULL; -#endif } return ret; } @@ -1345,13 +813,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { -#if defined(VERSION_SH) || defined(VERSION_CN) goto null_return; -#else - eu_stubbed_printf_0("Warning: Drop Voice"); - seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; - return NULL; -#endif } return ret; } @@ -1365,95 +827,28 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { -#if defined(VERSION_SH) || defined(VERSION_CN) goto null_return; -#else - eu_stubbed_printf_0("Warning: Drop Voice"); - seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; - return NULL; -#endif } return ret; -#if defined(VERSION_SH) || defined(VERSION_CN) null_return: seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; return NULL; -#endif } -#if defined(VERSION_JP) || defined(VERSION_US) -void reclaim_notes(void) { - struct Note *note; - s32 i; - s32 cond; - - for (i = 0; i < gMaxSimultaneousNotes; i++) { - note = &gNotes[i]; - if (note->parentLayer != NO_LAYER) { - cond = FALSE; - if (!note->parentLayer->enabled && note->priority >= NOTE_PRIORITY_MIN) { - cond = TRUE; - } else if (note->parentLayer->seqChannel == NULL) { - audio_list_push_back(&gLayerFreeList, ¬e->parentLayer->listItem); - seq_channel_layer_disable(note->parentLayer); - note->priority = NOTE_PRIORITY_STOPPING; - } else if (note->parentLayer->seqChannel->seqPlayer == NULL) { - sequence_channel_disable(note->parentLayer->seqChannel); - note->priority = NOTE_PRIORITY_STOPPING; - } else if (note->parentLayer->seqChannel->seqPlayer->muted) { - if (note->parentLayer->seqChannel->muteBehavior - & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES)) { - cond = TRUE; - } - } else { - cond = FALSE; - } - - if (cond) { - seq_channel_layer_note_release(note->parentLayer); - audio_list_remove(¬e->listItem); - audio_list_push_front(¬e->listItem.pool->disabled, ¬e->listItem); - note->priority = NOTE_PRIORITY_STOPPING; - } - } - } -} -#endif - void note_init_all(void) { struct Note *note; s32 i; for (i = 0; i < gMaxSimultaneousNotes; i++) { note = &gNotes[i]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note->noteSubEu = gZeroNoteSub; -#else - note->enabled = FALSE; - note->stereoStrongRight = FALSE; - note->stereoStrongLeft = FALSE; - note->stereoHeadsetEffects = FALSE; -#endif note->priority = NOTE_PRIORITY_DISABLED; -#if defined(VERSION_SH) || defined(VERSION_CN) note->unkSH34 = 0; -#endif note->parentLayer = NO_LAYER; note->wantedParentLayer = NO_LAYER; note->prevParentLayer = NO_LAYER; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) note->waveId = 0; -#else - note->reverbVol = 0; - note->usesHeadsetPanEffects = FALSE; - note->sampleCount = 0; - note->instOrWave = 0; - note->targetVolLeft = 0; - note->targetVolRight = 0; - note->frequency = 0.0f; - note->unused1 = 0x3f; -#endif note->attributes.velocity = 0.0f; note->adsrVolScale = 0; note->adsr.state = ADSR_STATE_DISABLED; @@ -1461,12 +856,6 @@ void note_init_all(void) { note->vibratoState.active = FALSE; note->portamento.cur = 0.0f; note->portamento.speed = 0.0f; -#if defined(VERSION_SH) || defined(VERSION_CN) note->synthesisState.synthesisBuffers = sound_alloc_uninitialized(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); -#elif defined(VERSION_EU) - note->synthesisState.synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); -#else - note->synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); -#endif } } diff --git a/src/audio/sh/playback.h b/src/audio/sh/playback.h new file mode 100644 index 00000000..bc464604 --- /dev/null +++ b/src/audio/sh/playback.h @@ -0,0 +1,41 @@ +#ifndef AUDIO_PLAYBACK_H +#define AUDIO_PLAYBACK_H + +#include + +#include "internal.h" + +// Mask bits denoting where to allocate notes from, according to a channel's +// noteAllocPolicy. Despite being checked as bitmask bits, the bits are not +// orthogonal; rather, the smallest bit wins, except for NOTE_ALLOC_LAYER, +// which *is* orthogonal to the other. SEQ implicitly includes CHANNEL. +// If none of the CHANNEL/SEQ/GLOBAL_FREELIST bits are set, all three locations +// are tried. +#define NOTE_ALLOC_LAYER 1 +#define NOTE_ALLOC_CHANNEL 2 +#define NOTE_ALLOC_SEQ 4 +#define NOTE_ALLOC_GLOBAL_FREELIST 8 + +void process_notes(void); +void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer); +void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer); +void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer); +void init_note_lists(struct NotePool *pool); +void init_note_free_list(void); +void note_pool_clear(struct NotePool *pool); +void note_pool_fill(struct NotePool *pool, s32 count); +void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item); +void audio_list_remove(struct AudioListItem *item); +struct Note *alloc_note(struct SequenceChannelLayer *seqLayer); +void reclaim_notes(void); +void note_init_all(void); +void note_set_vel_pan_reverb(struct Note *note, struct ReverbInfo *reverbInfo); +struct AudioBankSound *instrument_get_audio_bank_sound(struct Instrument *instrument, s32 semitone); +struct Instrument *get_instrument_inner(s32 bankId, s32 instId); +struct Drum *get_drum(s32 bankId, s32 drumId); +void note_init_volume(struct Note *note); +void note_set_frequency(struct Note *note, f32 frequency); +void note_enable(struct Note *note); +void note_disable(struct Note *note); + +#endif // AUDIO_PLAYBACK_H diff --git a/src/audio/port_sh.c b/src/audio/sh/port.c similarity index 93% rename from src/audio/port_sh.c rename to src/audio/sh/port.c index e96f7c32..6490a4be 100644 --- a/src/audio/port_sh.c +++ b/src/audio/sh/port.c @@ -1,8 +1,6 @@ -#if defined(VERSION_SH) || defined(VERSION_CN) -// TODO: merge this with port_eu.c - #include +#include "port.h" #include "data.h" #include "heap.h" #include "load.h" @@ -17,7 +15,6 @@ extern s32 D_SH_80314FC8; extern struct SPTask *D_SH_80314FCC; extern u8 D_SH_80315098; extern u8 D_SH_8031509C; -extern OSMesgQueue *D_SH_80350F68; void func_8031D690(s32 playerIndex, s32 numFrames); void seq_player_fade_to_zero_volume(s32 arg0, s32 numFrames); @@ -42,7 +39,7 @@ struct SPTask *create_next_audio_frame_task(void) { } return NULL; } - osSendMesg(D_SH_80350F38, (OSMesg) gAudioFrameCount, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueue0, (OSMesg) gAudioFrameCount, OS_MESG_NOBLOCK); gAudioTaskIndex ^= 1; gCurrAiBufferIndex++; @@ -63,7 +60,7 @@ struct SPTask *create_next_audio_frame_task(void) { decrease_sample_dma_ttls(); func_sh_802f41e4(gAudioResetStatus); - if (osRecvMesg(D_SH_80350F88, (OSMesg *) &sp38, OS_MESG_NOBLOCK) != -1) { + if (osRecvMesg(OSMesgQueue2, (OSMesg *) &sp38, OS_MESG_NOBLOCK) != -1) { if (gAudioResetStatus == 0) { gAudioResetStatus = 5; } @@ -73,7 +70,7 @@ struct SPTask *create_next_audio_frame_task(void) { if (gAudioResetStatus != 0) { if (audio_shut_down_and_reset_step() == 0) { if (gAudioResetStatus == 0) { - osSendMesg(D_SH_80350FA8, (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueue3, (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK); } D_SH_80314FCC = 0; return NULL; @@ -100,10 +97,10 @@ struct SPTask *create_next_audio_frame_task(void) { gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength; } - if (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1) { + if (osRecvMesg(OSMesgQueue1, (OSMesg *) &sp34, 0) != -1) { do { func_802ad7ec(sp34); - } while (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1); + } while (osRecvMesg(OSMesgQueue1, (OSMesg *) &sp34, 0) != -1); } flags = 0; @@ -251,14 +248,14 @@ void func_8031D690(s32 playerIndex, s32 fadeInTime) { void port_eu_init_queues(void) { D_SH_80350F18 = 0; D_SH_80350F19 = 0; - D_SH_80350F38 = &D_SH_80350F20; - D_SH_80350F68 = &D_SH_80350F50; - D_SH_80350F88 = &D_SH_80350F70; - D_SH_80350FA8 = &D_SH_80350F90; - osCreateMesgQueue(D_SH_80350F38, D_SH_80350F1C, 1); - osCreateMesgQueue(D_SH_80350F68, D_SH_80350F40, 4); - osCreateMesgQueue(D_SH_80350F88, D_SH_80350F6C, 1); - osCreateMesgQueue(D_SH_80350FA8, D_SH_80350F8C, 1); + OSMesgQueue0 = &OSMesgQueue0Data; + OSMesgQueue1 = &OSMesgQueue1Data; + OSMesgQueue2 = &OSMesgQueue2Data; + OSMesgQueue3 = &OSMesgQueue3Data; + osCreateMesgQueue(OSMesgQueue0, OSMesg0, 1); + osCreateMesgQueue(OSMesgQueue1, OSMesg1, 4); + osCreateMesgQueue(OSMesgQueue2, OSMesg2, 1); + osCreateMesgQueue(OSMesgQueue3, OSMesg3, 1); } extern struct EuAudioCmd sAudioCmd[0x100]; @@ -272,22 +269,22 @@ void func_802ad6f0(s32 arg0, s32 *arg1) { } } -void func_802ad728(u32 arg0, f32 arg1) { +void port_cmd_f32(u32 arg0, f32 arg1) { func_802ad6f0(arg0, (s32 *) &arg1); } -void func_802ad74c(u32 arg0, u32 arg1) { +void port_cmd_u32(u32 arg0, u32 arg1) { func_802ad6f0(arg0, (s32 *) &arg1); } -void func_802ad770(u32 arg0, s8 arg1) { +void port_cmd_s8(u32 arg0, s8 arg1) { s32 sp1C = arg1 << 24; func_802ad6f0(arg0, &sp1C); } char shindouDebugPrint133[] = "AudioSend: %d -> %d (%d)\n"; -void func_sh_802F64C8(void) { +void func_802ad7a0(void) { static s32 D_SH_8031503C = 0; s32 mesg; @@ -295,7 +292,7 @@ void func_sh_802F64C8(void) { D_SH_8031503C = (D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff; } mesg = ((D_SH_80350F19 & 0xff) << 8) | (D_SH_80350F18 & 0xff); - osSendMesg(D_SH_80350F68, (OSMesg)mesg, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueue1, (OSMesg)mesg, OS_MESG_NOBLOCK); D_SH_80350F19 = D_SH_80350F18; } @@ -440,7 +437,7 @@ s32 func_sh_802f6900(void) { s32 ret; s32 sp18; - ret = osRecvMesg(D_SH_80350FA8, (OSMesg *) &sp18, 0); + ret = osRecvMesg(OSMesgQueue3, (OSMesg *) &sp18, 0); if (ret == -1) { return 0; @@ -459,9 +456,9 @@ void func_sh_802f6958(OSMesg mesg) { do { a = -1; - } while (osRecvMesg(D_SH_80350FA8, &recvMesg, OS_MESG_NOBLOCK) != a); + } while (osRecvMesg(OSMesgQueue3, &recvMesg, OS_MESG_NOBLOCK) != a); func_sh_802f6540(); - osSendMesg(D_SH_80350F88, mesg, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueue2, mesg, OS_MESG_NOBLOCK); } void func_sh_802f69cc(void) { @@ -563,4 +560,3 @@ char shindouDebugPrint198[] = "Macro Level Over Error!\n"; char shindouDebugPrint199[] = "Group:Undefine upper C0h command (%x)\n"; char shindouDebugPrint200[] = "Group:Undefined Command\n"; -#endif diff --git a/src/audio/sh/port.h b/src/audio/sh/port.h new file mode 100644 index 00000000..e9b51d51 --- /dev/null +++ b/src/audio/sh/port.h @@ -0,0 +1,29 @@ +#ifndef AUDIO_PORT_H +#define AUDIO_PORT_H + +#include + +extern OSMesg OSMesg0[1]; +extern OSMesgQueue OSMesgQueue0Data; +extern OSMesgQueue *OSMesgQueue0; + +extern OSMesg OSMesg1[4]; +extern OSMesgQueue OSMesgQueue1Data; +extern OSMesgQueue *OSMesgQueue1; + +extern OSMesg OSMesg2[1]; +extern OSMesgQueue OSMesgQueue2Data; +extern OSMesgQueue *OSMesgQueue2; + +extern OSMesg OSMesg3[1]; +extern OSMesgQueue OSMesgQueue3Data; +extern OSMesgQueue *OSMesgQueue3; + +// main thread -> sound thread dispatchers +void port_cmd_f32(u32 arg0, f32 arg1); +void port_cmd_u32(u32 arg0, u32 arg1); +void port_cmd_s8(u32 arg0, s8 arg1); + +void func_802ad7a0(void); + +#endif // AUDIO_PORT_H diff --git a/src/audio/seqplayer.c b/src/audio/sh/seqplayer.c similarity index 61% rename from src/audio/seqplayer.c rename to src/audio/sh/seqplayer.c index b65fa609..44541fbf 100644 --- a/src/audio/seqplayer.c +++ b/src/audio/sh/seqplayer.c @@ -2,7 +2,6 @@ #include "data.h" #include "effects.h" -#include "external.h" #include "heap.h" #include "load.h" #include "seqplayer.h" @@ -15,13 +14,11 @@ #define PORTAMENTO_MODE_4 4 #define PORTAMENTO_MODE_5 5 -#if defined(VERSION_SH) || defined(VERSION_CN) void seq_channel_layer_process_script_part1(struct SequenceChannelLayer *layer); s32 seq_channel_layer_process_script_part2(struct SequenceChannelLayer *layer); s32 seq_channel_layer_process_script_part3(struct SequenceChannelLayer *layer, s32 cmd); s32 seq_channel_layer_process_script_part4(struct SequenceChannelLayer *layer, s32 cmd); s32 seq_channel_layer_process_script_part5(struct SequenceChannelLayer *layer, s32 cmd); -#endif void seq_channel_layer_process_script(struct SequenceChannelLayer *layer); void sequence_channel_process_script(struct SequenceChannel *seqChannel); u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, @@ -38,7 +35,6 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->stereoHeadsetEffects = FALSE; seqChannel->transposition = 0; seqChannel->largeNotes = FALSE; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->bookOffset = 0; seqChannel->changes.as_u8 = 0xff; seqChannel->scriptState.depth = 0; @@ -46,30 +42,14 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->panChannelWeight = 0x80; seqChannel->noteUnused = NULL; seqChannel->reverbIndex = 0; -#else - seqChannel->scriptState.depth = 0; - seqChannel->volume = 1.0f; - seqChannel->volumeScale = 1.0f; - seqChannel->freqScale = 1.0f; - seqChannel->pan = 0.5f; - seqChannel->panChannelWeight = 1.0f; - seqChannel->noteUnused = NULL; -#endif seqChannel->reverbVol = 0; -#if defined(VERSION_SH) || defined(VERSION_CN) seqChannel->synthesisVolume = 0; -#endif seqChannel->notePriority = NOTE_PRIORITY_DEFAULT; -#if defined(VERSION_SH) || defined(VERSION_CN) seqChannel->unkSH06 = 1; -#endif seqChannel->delay = 0; seqChannel->adsr.envelope = gDefaultEnvelope; seqChannel->adsr.releaseRate = 0x20; seqChannel->adsr.sustain = 0; -#if defined(VERSION_JP) || defined(VERSION_US) - seqChannel->updatesPerFrameUnused = gAudioUpdatesPerFrame; -#endif seqChannel->vibratoRateTarget = 0x800; seqChannel->vibratoRateStart = 0x800; seqChannel->vibratoExtentTarget = 0; @@ -77,14 +57,10 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->vibratoRateChangeDelay = 0; seqChannel->vibratoExtentChangeDelay = 0; seqChannel->vibratoDelay = 0; -#if defined(VERSION_SH) || defined(VERSION_CN) seqChannel->filter = NULL; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->volume = 1.0f; seqChannel->volumeScale = 1.0f; seqChannel->freqScale = 1.0f; -#endif for (i = 0; i < 8; i++) { seqChannel->soundScriptIO[i] = -1; @@ -98,9 +74,7 @@ s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { struct SequenceChannelLayer *layer; if (seqChannel->layers[layerIndex] == NULL) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) struct SequenceChannelLayer *layer; -#endif layer = audio_list_pop_back(&gLayerFreeList); seqChannel->layers[layerIndex] = layer; if (layer == NULL) { @@ -119,36 +93,23 @@ s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { layer->stopSomething = FALSE; layer->continuousNotes = FALSE; layer->finished = FALSE; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) layer->ignoreDrumPan = FALSE; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) layer->reverbBits.asByte = 0x40; -#endif layer->portamento.mode = 0; layer->scriptState.depth = 0; layer->status = SOUND_LOAD_STATUS_NOT_LOADED; layer->noteDuration = 0x80; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) layer->pan = 0x40; -#endif layer->transposition = 0; layer->delay = 0; layer->duration = 0; layer->delayUnused = 0; layer->note = NULL; layer->instrument = NULL; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) layer->freqScale = 1.0f; layer->velocitySquare = 0.0f; -#if defined(VERSION_SH) || defined(VERSION_CN) layer->freqScaleMultiplier = 1.0f; -#endif layer->instOrWave = 0xff; -#else - layer->velocitySquare = 0.0f; - layer->pan = 0.5f; -#endif return 0; } @@ -164,19 +125,7 @@ void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex) struct SequenceChannelLayer *layer = seqChannel->layers[layerIndex]; if (layer != NULL) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) audio_list_push_back(&gLayerFreeList, &layer->listItem); -#else - struct AudioListItem *item = &layer->listItem; - if (item->prev == NULL) { - gLayerFreeList.prev->next = item; - item->prev = gLayerFreeList.prev; - item->next = &gLayerFreeList; - gLayerFreeList.prev = item; - gLayerFreeList.u.count++; - item->pool = gLayerFreeList.pool; - } -#endif seq_channel_layer_disable(layer); seqChannel->layers[layerIndex] = NULL; } @@ -197,11 +146,7 @@ struct SequenceChannel *allocate_sequence_channel(void) { s32 i; for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { if (gSequenceChannels[i].seqPlayer == NULL) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) return &gSequenceChannels[i]; -#else - return gSequenceChannels + i; -#endif } } return &gSequenceChannelNone; @@ -232,11 +177,7 @@ void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channel seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy; } } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) channelBits = channelBits >> 1; -#else - channelBits >>= 1; -#endif } } @@ -253,21 +194,12 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan sequence_channel_disable(seqChannel); seqChannel->seqPlayer = NULL; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) else { -#ifdef VERSION_EU - stubbed_printf("Audio:Track: Warning SUBTRACK PARENT CHANGED\n"); -#endif } -#endif seqPlayer->channels[i] = &gSequenceChannelNone; } } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) channelBits = channelBits >> 1; -#else - channelBits >>= 1; -#endif } } @@ -275,20 +207,6 @@ void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; s32 i; if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { -#ifdef VERSION_EU - struct SequencePlayer *bgMusic = &gSequencePlayers[0]; - struct SequencePlayer *miscMusic = &gSequencePlayers[1]; - - if (seqPlayer == bgMusic) { - stubbed_printf("GROUP 0:"); - } else if (seqPlayer == miscMusic) { - stubbed_printf("GROUP 1:"); - } else { - stubbed_printf("SEQID %d,BANKID %d\n", - seqPlayer->seqId, seqPlayer->defaultBank[0]); - } - stubbed_printf("ERR:SUBTRACK %d NOT ALLOCATED\n", channelIndex); -#endif } else { seqChannel->enabled = TRUE; seqChannel->finished = FALSE; @@ -310,41 +228,25 @@ void sequence_player_disable(struct SequencePlayer *seqPlayer) { seqPlayer->enabled = FALSE; if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) -#if defined(VERSION_SH) || defined(VERSION_CN) && gSeqLoadStatus[seqPlayer->seqId] != 5 -#endif ) { gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_DISCARDABLE; } if (IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) -#if defined(VERSION_SH) || defined(VERSION_CN) && gBankLoadStatus[seqPlayer->defaultBank[0]] != 5 -#endif ) { -#if defined(VERSION_SH) || defined(VERSION_CN) gBankLoadStatus[seqPlayer->defaultBank[0]] = 4; -#else - gBankLoadStatus[seqPlayer->defaultBank[0]] = SOUND_LOAD_STATUS_DISCARDABLE; -#endif } // (Note that if this is called from alloc_bank_or_seq, the side will get swapped // later in that function. Thus, we signal that we want to load into the slot // of the bank that we no longer need.) -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[0].id) { gBankLoadedPool.temporary.nextSide = 1; } else if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[1].id) { gBankLoadedPool.temporary.nextSide = 0; } -#else - if (gBankLoadedPool.temporary.entries[0].id == seqPlayer->defaultBank[0]) { - gBankLoadedPool.temporary.nextSide = 1; - } else if (gBankLoadedPool.temporary.entries[1].id == seqPlayer->defaultBank[0]) { - gBankLoadedPool.temporary.nextSide = 0; - } -#endif } /** @@ -387,23 +289,14 @@ void init_layer_freelist(void) { gLayerFreeList.pool = NULL; for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) gSequenceLayers[i].listItem.u.value = &gSequenceLayers[i]; -#else - gSequenceLayers[i].listItem.u.value = gSequenceLayers + i; -#endif gSequenceLayers[i].listItem.prev = NULL; audio_list_push_back(&gLayerFreeList, &gSequenceLayers[i].listItem); } } u8 m64_read_u8(struct M64ScriptState *state) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) return *(state->pc++); -#else - u8 *midiArg = state->pc++; - return *midiArg; -#endif } s16 m64_read_s16(struct M64ScriptState *state) { @@ -421,7 +314,6 @@ u16 m64_read_compressed_u16(struct M64ScriptState *state) { return ret; } -#if defined(VERSION_SH) || defined(VERSION_CN) void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { s32 cmd; @@ -456,525 +348,7 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { } } } -#elif defined(VERSION_EU) -void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { - struct SequencePlayer *seqPlayer; - struct SequenceChannel *seqChannel; -#ifdef VERSION_EU - UNUSED u32 pad0; -#endif - struct M64ScriptState *state; - struct Portamento *portamento; - struct AudioBankSound *sound; - struct Instrument *instrument; - struct Drum *drum; - s32 temp_a0_5; -#ifdef VERSION_EU - u16 sp3A; - s32 sameSound; -#endif - UNUSED u32 pad1; -#ifndef VERSION_EU - u8 sameSound; -#endif - u8 cmd; - UNUSED u8 cmdSemitone; -#ifndef VERSION_EU - u16 sp3A; -#endif - f32 tuning; - s32 vel; - UNUSED s32 usedSemitone; - f32 freqScale; -#ifndef VERSION_EU - UNUSED f32 sp24; -#endif - f32 temp_f12; - f32 temp_f2; - sameSound = TRUE; - if (layer->enabled == FALSE) { - return; - } - - if (layer->delay > 1) { - layer->delay--; - if (!layer->stopSomething && layer->delay <= layer->duration) { - seq_channel_layer_note_decay(layer); - layer->stopSomething = TRUE; - } - return; - } - - if (!layer->continuousNotes) { - seq_channel_layer_note_decay(layer); - } - - if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 || - PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) { - layer->portamento.mode = 0; - } - - seqChannel = layer->seqChannel; - seqPlayer = seqChannel->seqPlayer; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - layer->notePropertiesNeedInit = TRUE; -#endif - - for (;;) { - state = &layer->scriptState; - cmd = m64_read_u8(state); - - if (cmd <= 0xc0) { - break; - } - - switch (cmd) { - case 0xff: // layer_end; function return or end of script - if (state->depth == 0) { - // N.B. this function call is *not* inlined even though it's - // within the same file, unlike in the rest of this function. - seq_channel_layer_disable(layer); - return; - } - state->pc = state->stack[--state->depth]; - break; - - case 0xfc: // layer_call - if (0 && state->depth >= 4) { - eu_stubbed_printf_0("Macro Level Over Error!\n"); - } - sp3A = m64_read_s16(state); - state->stack[state->depth++] = state->pc; - state->pc = seqPlayer->seqData + sp3A; - break; - - case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) - if (0 && state->depth >= 4) { - eu_stubbed_printf_0("Macro Level Over Error!\n"); - } - state->remLoopIters[state->depth] = m64_read_u8(state); - state->stack[state->depth++] = state->pc; - break; - - case 0xf7: // layer_loopend - if (--state->remLoopIters[state->depth - 1] != 0) { - state->pc = state->stack[state->depth - 1]; - } else { - state->depth--; - } - break; - - case 0xfb: // layer_jump - sp3A = m64_read_s16(state); - state->pc = seqPlayer->seqData + sp3A; - break; - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - case 0xf4: - state->pc += (s8)m64_read_u8(state); - break; -#endif - - case 0xc1: // layer_setshortnotevelocity - case 0xca: // layer_setpan - temp_a0_5 = *(state->pc++); - if (cmd == 0xc1) { - layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5); - } else { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - layer->pan = temp_a0_5; -#else - layer->pan = (f32) temp_a0_5 / US_FLOAT(128.0); -#endif - } - break; - - case 0xc2: // layer_transpose; set transposition in semitones - case 0xc9: // layer_setshortnoteduration - temp_a0_5 = *(state->pc++); - if (cmd == 0xc9) { - layer->noteDuration = temp_a0_5; - } else { - layer->transposition = temp_a0_5; - } - break; - - case 0xc4: // layer_somethingon - case 0xc5: // layer_somethingoff - if (cmd == 0xc4) { - layer->continuousNotes = TRUE; - } else { - layer->continuousNotes = FALSE; - } - seq_channel_layer_note_decay(layer); - break; - - case 0xc3: // layer_setshortnotedefaultplaypercentage - sp3A = m64_read_compressed_u16(state); - layer->shortNoteDefaultPlayPercentage = sp3A; - break; - - case 0xc6: // layer_setinstr - cmd = m64_read_u8(state); -#if defined(VERSION_JP) || defined(VERSION_US) - if (cmd < 127) { - cmd = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr); - } -#else - if (cmd >= 0x7f) { - if (cmd == 0x7f) { - layer->instOrWave = 0; - } else { - layer->instOrWave = cmd; - layer->instrument = NULL; - } - - if (1) { - } - - if (cmd == 0xff) { - layer->adsr.releaseRate = 0; - } - break; - } - - if ((layer->instOrWave = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr)) == 0) { - eu_stubbed_printf_1("WARNING: NPRG: cannot change %d\n", cmd); - layer->instOrWave = 0xff; - } -#endif - break; - - case 0xc7: // layer_portamento - layer->portamento.mode = m64_read_u8(state); - - // cmd is reused for the portamento's semitone - cmd = m64_read_u8(state) + seqChannel->transposition + - layer->transposition + seqPlayer->transposition; - - if (cmd >= 0x80) { - cmd = 0; - } - - layer->portamentoTargetNote = cmd; - - // If special, the next param is u8 instead of var - if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { - layer->portamentoTime = *((state)->pc++); - break; - } - - sp3A = m64_read_compressed_u16(state); - layer->portamentoTime = sp3A; - break; - - case 0xc8: // layer_disableportamento - layer->portamento.mode = 0; - break; - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - case 0xcb: - sp3A = m64_read_s16(state); - layer->adsr.envelope = (struct AdsrEnvelope *) (seqPlayer->seqData + sp3A); - layer->adsr.releaseRate = m64_read_u8(state); - break; - - case 0xcc: - layer->ignoreDrumPan = TRUE; - break; -#endif - - default: - switch (cmd & 0xf0) { - case 0xd0: // layer_setshortnotevelocityfromtable - sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xf]; - layer->velocitySquare = (f32)(sp3A * sp3A); - break; - case 0xe0: // layer_setshortnotedurationfromtable - layer->noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf]; - break; - default: - eu_stubbed_printf_1("Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n", cmd); - break; - } - } - } - - if (cmd == 0xc0) { // layer_delay - layer->delay = m64_read_compressed_u16(state); - layer->stopSomething = TRUE; - } else { - layer->stopSomething = FALSE; - - if (seqChannel->largeNotes == TRUE) { - switch (cmd & 0xc0) { - case 0x00: // layer_note0 (play percentage, velocity, duration) - sp3A = m64_read_compressed_u16(state); - vel = *(state->pc++); - layer->noteDuration = *(state->pc++); - layer->playPercentage = sp3A; - break; - - case 0x40: // layer_note1 (play percentage, velocity) - sp3A = m64_read_compressed_u16(state); - vel = *(state->pc++); - layer->noteDuration = 0; - layer->playPercentage = sp3A; - break; - - case 0x80: // layer_note2 (velocity, duration; uses last play percentage) - sp3A = layer->playPercentage; - vel = *(state->pc++); - layer->noteDuration = *(state->pc++); - break; - } - - // the remaining bits are used for the semitone - cmd -= (cmd & 0xc0); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - layer->velocitySquare = (f32)(vel) * (f32)vel; -#else - layer->velocitySquare = vel * vel; -#endif - } else { - switch (cmd & 0xc0) { - case 0x00: // play note, type 0 (play percentage) - sp3A = m64_read_compressed_u16(state); - layer->playPercentage = sp3A; - break; - - case 0x40: // play note, type 1 (uses default play percentage) - sp3A = layer->shortNoteDefaultPlayPercentage; - break; - - case 0x80: // play note, type 2 (uses last play percentage) - sp3A = layer->playPercentage; - break; - } - - // the remaining bits are used for the semitone - cmd -= cmd & 0xc0; - } - - layer->delay = sp3A; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - layer->duration = layer->noteDuration * sp3A >> 8; -#else - layer->duration = layer->noteDuration * sp3A / 256; -#endif - if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0) - || seqChannel->stopSomething2 -#if defined(VERSION_JP) || defined(VERSION_US) - || !seqChannel->hasInstrument -#endif - ) { - layer->stopSomething = TRUE; - } else { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - s32 temp = layer->instOrWave; - if (temp == 0xff) { - temp = seqChannel->instOrWave; - } - if (temp == 0) -#else - if (seqChannel->instOrWave == 0) -#endif - { // drum - // cmd is reused for the drum semitone - cmd += seqChannel->transposition + layer->transposition; - -#if defined(VERSION_EU) - drum = get_drum(seqChannel->bankId, cmd); -#else - if (cmd >= gCtlEntries[seqChannel->bankId].numDrums) { - cmd = gCtlEntries[seqChannel->bankId].numDrums; - if (cmd == 0) { - // this goto looks a bit like a function return... - layer->stopSomething = TRUE; - goto skip; - } - - cmd--; - } - - drum = gCtlEntries[seqChannel->bankId].drums[cmd]; -#endif - if (drum == NULL) { - layer->stopSomething = TRUE; - } else { - layer->adsr.envelope = drum->envelope; - layer->adsr.releaseRate = drum->releaseRate; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - if (!layer->ignoreDrumPan) { - layer->pan = drum->pan; - } -#else - layer->pan = FLOAT_CAST(drum->pan) / US_FLOAT(128.0); -#endif - layer->sound = &drum->sound; - layer->freqScale = layer->sound->tuning; - } -#if defined(VERSION_JP) || defined(VERSION_US) || defined(VERSION_SH) - skip:; -#endif - } else { // instrument - // cmd is reused for the instrument semitone - cmd += seqPlayer->transposition + seqChannel->transposition + layer->transposition; - - if (cmd >= 0x80) { - layer->stopSomething = TRUE; - } else { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - if (layer->instOrWave == 0xffu) { - instrument = seqChannel->instrument; - } else { - instrument = layer->instrument; - } -#else - instrument = layer->instrument; - if (instrument == NULL) { - instrument = seqChannel->instrument; - } -#endif - - if (layer->portamento.mode != 0) { - if (layer->portamentoTargetNote < cmd) { - vel = cmd; - } else { - vel = layer->portamentoTargetNote; - } - - if (instrument != NULL) { -#if defined(VERSION_EU) - sound = instrument_get_audio_bank_sound(instrument, vel); -#else - sound = (u8) vel < instrument->normalRangeLo ? &instrument->lowNotesSound - : (u8) vel <= instrument->normalRangeHi ? - &instrument->normalNotesSound : &instrument->highNotesSound; -#endif - sameSound = (sound == layer->sound); - layer->sound = sound; - tuning = sound->tuning; - } else { - layer->sound = NULL; - tuning = 1.0f; - } - - temp_f2 = gNoteFrequencies[cmd] * tuning; - temp_f12 = gNoteFrequencies[layer->portamentoTargetNote] * tuning; - - portamento = &layer->portamento; - switch (PORTAMENTO_MODE(layer->portamento)) { - case PORTAMENTO_MODE_1: - case PORTAMENTO_MODE_3: - case PORTAMENTO_MODE_5: -#if defined(VERSION_JP) || defined(VERSION_US) - sp24 = temp_f2; -#endif - freqScale = temp_f12; - break; - - case PORTAMENTO_MODE_2: - case PORTAMENTO_MODE_4: -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - default: -#endif - freqScale = temp_f2; -#if defined(VERSION_JP) || defined(VERSION_US) - sp24 = temp_f12; -#endif - break; - } - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - portamento->extent = temp_f2 / freqScale - 1.0f; -#else - portamento->extent = sp24 / freqScale - US_FLOAT(1.0); -#endif - - if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { - portamento->speed = US_FLOAT(32512.0) * FLOAT_CAST(seqPlayer->tempo) - / ((f32) layer->delay * (f32) gTempoInternalToExternal - * FLOAT_CAST(layer->portamentoTime)); - } else { - portamento->speed = US_FLOAT(127.0) / FLOAT_CAST(layer->portamentoTime); - } - portamento->cur = 0.0f; - layer->freqScale = freqScale; - if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_5) { - layer->portamentoTargetNote = cmd; - } - } else if (instrument != NULL) { -#if defined(VERSION_EU) - sound = instrument_get_audio_bank_sound(instrument, cmd); -#else - sound = cmd < instrument->normalRangeLo ? - &instrument->lowNotesSound : cmd <= instrument->normalRangeHi ? - &instrument->normalNotesSound : &instrument->highNotesSound; -#endif - sameSound = (sound == layer->sound); - layer->sound = sound; - layer->freqScale = gNoteFrequencies[cmd] * sound->tuning; - } else { - layer->sound = NULL; - layer->freqScale = gNoteFrequencies[cmd]; - } - } - } - layer->delayUnused = layer->delay; - } - } - - if (layer->stopSomething == TRUE) { - if (layer->note != NULL || layer->continuousNotes) { - seq_channel_layer_note_decay(layer); - } - return; - } - - cmd = FALSE; - if (!layer->continuousNotes) { - cmd = TRUE; - } else if (layer->note == NULL || layer->status == SOUND_LOAD_STATUS_NOT_LOADED) { - cmd = TRUE; - } else if (sameSound == FALSE) { - seq_channel_layer_note_decay(layer); - cmd = TRUE; - } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - else if (layer != layer->note->parentLayer) { - cmd = TRUE; - } -#endif - else if (layer->sound == NULL) { - init_synthetic_wave(layer->note, layer); - } - - if (cmd != FALSE) { - layer->note = alloc_note(layer); - } - - if (layer->note != NULL && layer->note->parentLayer == layer) { - note_vibrato_init(layer->note); - } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) - if (seqChannel) { - } -#endif -} - -#ifdef VERSION_EU -u8 audioString106[] = "Audio: Note:Velocity Error %d\n"; -u8 audioString107[] = "Error: Your assignchannel is stolen.\n"; -#endif - -#else -// US/JP version with macros to simulate inlining by copt. Edit if you dare. -#include "copt/seq_channel_layer_process_script_copt.inc.c" -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) void seq_channel_layer_process_script_part1(struct SequenceChannelLayer *layer) { if (!layer->continuousNotes) { seq_channel_layer_note_decay(layer); @@ -1299,11 +673,11 @@ s32 seq_channel_layer_process_script_part4(struct SequenceChannelLayer *layer, s portamento->extent = sp24 / freqScale - 1.0f; if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { - portamento->speed = US_FLOAT(32512.0) * FLOAT_CAST(seqPlayer->tempo) + portamento->speed = 32512.0f * FLOAT_CAST(seqPlayer->tempo) / ((f32) layer->delay * (f32) gTempoInternalToExternal * FLOAT_CAST(layer->portamentoTime)); } else { - portamento->speed = US_FLOAT(127.0) / FLOAT_CAST(layer->portamentoTime); + portamento->speed = 127.0f / FLOAT_CAST(layer->portamentoTime); } portamento->cur = 0.0f; layer->freqScale = freqScale; @@ -1399,11 +773,9 @@ s32 seq_channel_layer_process_script_part3(struct SequenceChannelLayer *layer, s return cmd; } -#endif u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) { struct Instrument *inst; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) inst = get_instrument_inner(seqChannel->bankId, instId); if (inst == NULL) { *instOut = NULL; @@ -1414,47 +786,6 @@ u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrume *instOut = inst; instId++; return instId; -#else - UNUSED u32 pad; - - if (instId >= gCtlEntries[seqChannel->bankId].numInstruments) { - instId = gCtlEntries[seqChannel->bankId].numInstruments; - if (instId == 0) { - return 0; - } - instId--; - } - - inst = gCtlEntries[seqChannel->bankId].instruments[instId]; - if (inst == NULL) { - struct SequenceChannel seqChannelCpy = *seqChannel; - - while (instId != 0xff) { - inst = gCtlEntries[seqChannelCpy.bankId].instruments[instId]; - if (inst != NULL) { - break; - } - instId--; - } - } - - if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst - && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start - + gBankLoadedPool.persistent.pool.size)) - || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst - && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start - + gBankLoadedPool.temporary.pool.size))) { - adsr->envelope = inst->envelope; - adsr->releaseRate = inst->releaseRate; - *instOut = inst; - instId++; - return instId; - } - - gAudioErrorFlags = instId + 0x20000; - *instOut = NULL; - return 0; -#endif } void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { @@ -1465,14 +796,8 @@ void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { seqChannel->instOrWave = 0; seqChannel->instrument = (struct Instrument *) 1; } else { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if ((seqChannel->instOrWave = get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr)) == 0) -#else - seqChannel->instOrWave = - get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr); - if (seqChannel->instOrWave == 0) -#endif { seqChannel->hasInstrument = FALSE; return; @@ -1482,7 +807,7 @@ void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { } void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume) { - seqChannel->volume = FLOAT_CAST(volume) / US_FLOAT(127.0); + seqChannel->volume = FLOAT_CAST(volume) / 127.0f; } void sequence_channel_process_script(struct SequenceChannel *seqChannel) { @@ -1523,46 +848,19 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (seqChannel->delay == 0) { for (;;) { cmd = m64_read_u8(state); -#if defined(VERSION_JP) || defined(VERSION_US) - if (cmd == 0xff) { // chan_end - if (state->depth == 0) { - sequence_channel_disable(seqChannel); - break; - } - state->depth--, state->pc = state->stack[state->depth]; - } - if (cmd == 0xfe) { // chan_delay1 - break; - } - if (cmd == 0xfd) { // chan_delay - seqChannel->delay = m64_read_compressed_u16(state); - break; - } - if (cmd == 0xf3) { // chan_hang - seqChannel->stopScript = TRUE; - break; - } -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) if (cmd >= 0xb0) -#else - if (cmd > 0xc0) -#endif { switch (cmd) { case 0xff: // chan_end -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (state->depth == 0) { sequence_channel_disable(seqChannel); goto out; } else { state->pc = state->stack[--state->depth]; } -#endif break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xfe: // chan_delay1 goto out; @@ -1573,17 +871,12 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xea: seqChannel->stopScript = TRUE; goto out; -#endif case 0xfc: // chan_call if (0 && state->depth >= 4) { eu_stubbed_printf_0("Audio:Track :Call Macro Level Over Error!\n"); } sp5A = m64_read_s16(state); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) state->stack[state->depth++] = state->pc; -#else - state->depth++, state->stack[state->depth - 1] = state->pc; -#endif state->pc = seqPlayer->seqData + sp5A; break; @@ -1592,11 +885,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { eu_stubbed_printf_0("Audio:Track :Loops Macro Level Over Error!\n"); } state->remLoopIters[state->depth] = m64_read_u8(state); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) state->stack[state->depth++] = state->pc; -#else - state->depth++, state->stack[state->depth - 1] = state->pc; -#endif break; case 0xf7: // chan_loopend @@ -1629,7 +918,6 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { state->pc = seqPlayer->seqData + sp5A; break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xf4: // chan_jump_rel case 0xf3: // chan_beqz_rel case 0xf2: // chan_bltz_rel @@ -1642,22 +930,13 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } state->pc += temp; break; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xf1: // chan_reservenotes -#else - case 0xf2: // chan_reservenotes -#endif note_pool_clear(&seqChannel->notePool); note_pool_fill(&seqChannel->notePool, m64_read_u8(state)); break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xf0: // chan_unreservenotes -#else - case 0xf1: // chan_unreservenotes -#endif note_pool_clear(&seqChannel->notePool); break; @@ -1668,18 +947,12 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xc5: // chan_dynsetdyntable if (value != -1) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqData = (*seqChannel->dynTable)[value]; sp38 = (u16)((seqData[0] << 8) + seqData[1]); seqChannel->dynTable = (void *) (seqPlayer->seqData + sp38); -#else - sp5A = (u16)((((*seqChannel->dynTable)[value])[0] << 8) + (((*seqChannel->dynTable)[value])[1])); - seqChannel->dynTable = (void *) (seqPlayer->seqData + sp5A); -#endif } break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xeb: // chan_setbankandinstr cmd = m64_read_u8(state); // Switch to the cmd's (0-indexed) bank in this sequence's @@ -1690,18 +963,13 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { loBits = *(sp38 + gAlBankSets); cmd = gAlBankSets[(s32)sp38 + loBits - cmd]; -#if defined(VERSION_SH) || defined(VERSION_CN) if (get_bank_or_seq(1, 2, cmd) != NULL) -#else - if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL) -#endif { seqChannel->bankId = cmd; } else { eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", cmd); } // fallthrough -#endif case 0xc1: // chan_setinstr ("set program"?) set_instrument(seqChannel, m64_read_u8(state)); @@ -1717,63 +985,41 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xdf: // chan_setvol sequence_channel_set_volume(seqChannel, m64_read_u8(state)); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->changes.as_bitfields.volume = TRUE; -#endif break; case 0xe0: // chan_setvolscale - seqChannel->volumeScale = FLOAT_CAST(m64_read_u8(state)) / US_FLOAT(128.0); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) + seqChannel->volumeScale = FLOAT_CAST(m64_read_u8(state)) / 128.0f; seqChannel->changes.as_bitfields.volume = TRUE; -#endif break; case 0xde: // chan_freqscale; pitch bend using raw frequency multiplier N/2^15 (N is u16) sp5A = m64_read_s16(state); - seqChannel->freqScale = FLOAT_CAST(sp5A) / US_FLOAT(32768.0); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) + seqChannel->freqScale = FLOAT_CAST(sp5A) / 32768.0f; seqChannel->changes.as_bitfields.freqScale = TRUE; -#endif break; case 0xd3: // chan_pitchbend; pitch bend by <= 1 octave in either direction (-127..127) // (m64_read_u8(state) is really s8 here) -#if defined(VERSION_SH) || defined(VERSION_CN) cmd = m64_read_u8(state) + 128; -#else - cmd = m64_read_u8(state) + 127; -#endif seqChannel->freqScale = gPitchBendFrequencyScale[cmd]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->changes.as_bitfields.freqScale = TRUE; -#endif break; -#if defined(VERSION_SH) || defined(VERSION_CN) case 0xee: cmd = m64_read_u8(state) + 0x80; seqChannel->freqScale = unk_sh_data_1[cmd]; seqChannel->changes.as_bitfields.freqScale = TRUE; break; -#endif case 0xdd: // chan_setpan -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->newPan = m64_read_u8(state); seqChannel->changes.as_bitfields.pan = TRUE; -#else - seqChannel->pan = FLOAT_CAST(m64_read_u8(state)) / US_FLOAT(128.0); -#endif break; case 0xdc: // chan_setpanmix; set proportion of pan to come from channel (0..128) -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->panChannelWeight = m64_read_u8(state); seqChannel->changes.as_bitfields.pan = TRUE; -#else - seqChannel->panChannelWeight = FLOAT_CAST(m64_read_u8(state)) / US_FLOAT(128.0); -#endif break; case 0xdb: // chan_transpose; set transposition in semitones @@ -1818,16 +1064,6 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { seqChannel->vibratoDelay = m64_read_u8(state) * 16; break; -#if defined(VERSION_JP) || defined(VERSION_US) - case 0xd6: // chan_setupdatesperframe_unimplemented - cmd = m64_read_u8(state); - if (cmd == 0) { - cmd = gAudioUpdatesPerFrame; - } - seqChannel->updatesPerFrameUnused = cmd; - break; -#endif - case 0xd4: // chan_setreverb seqChannel->reverbVol = m64_read_u8(state); break; @@ -1838,20 +1074,10 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { // bank set. Note that in the binary format (not in the JSON!) // the banks are listed backwards, so we counts from the back. // (gAlBankSets[offset] is number of banks) -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) sp38 = ((u16 *) gAlBankSets)[seqPlayer->seqId]; loBits = *(sp38 + gAlBankSets); cmd = gAlBankSets[(s32)sp38 + loBits - cmd]; -#else - sp5A = ((u16 *) gAlBankSets)[seqPlayer->seqId]; - loBits = *(sp5A + gAlBankSets); - cmd = gAlBankSets[sp5A + loBits - cmd]; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) if (get_bank_or_seq(1, 2, cmd) != NULL) -#else - if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL) -#endif { seqChannel->bankId = cmd; } else { @@ -1861,9 +1087,6 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xc7: // chan_writeseq; write to sequence data (!) { -#if defined(VERSION_JP) || defined(VERSION_US) - u8 *seqData; -#endif cmd = m64_read_u8(state); sp5A = m64_read_s16(state); seqData = seqPlayer->seqData + sp5A; @@ -1884,17 +1107,13 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } break; -#if defined(VERSION_SH) || defined(VERSION_CN) case 0xcd: sequence_channel_disable(seqPlayer->channels[m64_read_u8(state)]); break; -#endif case 0xca: // chan_setmutebhv seqChannel->muteBehavior = m64_read_u8(state); -#if defined(VERSION_SH) || defined(VERSION_CN) seqChannel->changes.as_bitfields.volume = TRUE; -#endif break; case 0xcb: // chan_readseq @@ -1902,7 +1121,6 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { value = seqPlayer->seqData[sp38]; break; -#if defined(VERSION_SH) || defined(VERSION_CN) case 0xce: seqChannel->unkC8 = m64_read_s16(state); break; @@ -1913,7 +1131,6 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { seqData[0] = (seqChannel->unkC8 >> 8) & 0xffff; seqData[1] = (seqChannel->unkC8) & 0xffff; break; -#endif case 0xd0: // chan_stereoheadseteffects seqChannel->stereoHeadsetEffects = m64_read_u8(state); @@ -1924,26 +1141,17 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { break; case 0xd2: // chan_setsustain -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqChannel->adsr.sustain = m64_read_u8(state); -#else - seqChannel->adsr.sustain = m64_read_u8(state) << 8; -#endif break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xe5: seqChannel->reverbIndex = m64_read_u8(state); break; -#endif case 0xe4: // chan_dyncall if (value != -1) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (state->depth >= 4) { eu_stubbed_printf_0("Audio:Track: CTBLCALL Macro Level Over Error!\n"); } -#endif seqData = (*seqChannel->dynTable)[value]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) state->stack[state->depth++] = state->pc; sp38 = (u16)((seqData[0] << 8) + seqData[1]); state->pc = seqPlayer->seqData + sp38; @@ -1951,15 +1159,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (0 && sp38 >= gSeqFileHeader->seqArray[seqPlayer->seqId].len) { eu_stubbed_printf_3("Err :Sub %x ,address %x:Undefined SubTrack Function %x", seqChannel, state->pc, sp38); } -#else - state->depth++, state->stack[state->depth - 1] = state->pc; - sp5A = ((seqData[0] << 8) + seqData[1]); - state->pc = seqPlayer->seqData + sp5A; -#endif } break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xe6: seqChannel->bookOffset = m64_read_u8(state); break; @@ -2001,7 +1203,6 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { break; case 0xe9: // chan_setnotepriority -#if defined(VERSION_SH) || defined(VERSION_CN) cmd = m64_read_u8(state); if ((cmd & 0xf) != 0) { seqChannel->notePriority = cmd & 0xf; @@ -2010,12 +1211,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (cmd != 0) { seqChannel->unkSH06 = cmd; } -#else - seqChannel->notePriority = m64_read_u8(state); -#endif break; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) case 0xed: seqChannel->synthesisVolume = m64_read_u8(state); break; @@ -2066,10 +1262,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xb6: value = (*seqChannel->dynTable)[0][value]; break; -#endif } } else { -#if defined(VERSION_SH) || defined(VERSION_CN) if (cmd >= 0x80) { loBits = cmd & 7; switch (cmd & 0xf8) { @@ -2102,11 +1296,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { break; } } else { -#endif loBits = cmd & 0xf; switch (cmd & 0xf0) { -#if defined(VERSION_SH) || defined(VERSION_CN) case 0x00: seqChannel->delay = loBits; goto out; @@ -2116,29 +1308,13 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (func_sh_802f47c8(seqChannel->bankId, (u8)value, &seqChannel->soundScriptIO[loBits]) == -1) { } break; -#else - case 0x00: // chan_testlayerfinished - if (seqChannel->layers[loBits] != NULL) { - value = seqChannel->layers[loBits]->finished; - } -#ifdef VERSION_EU - else { - value = -1; - } -#endif - break; -#endif // sh: 0x70 case 0x70: // chan_iowriteval; write data back to audio lib seqChannel->soundScriptIO[loBits] = value; break; -#if defined(VERSION_SH) || defined(VERSION_CN) case 0x60: -#else - case 0x80: // chan_ioreadval; read data from audio lib -#endif value = seqChannel->soundScriptIO[loBits]; if (loBits < 4) { seqChannel->soundScriptIO[loBits] = -1; @@ -2150,58 +1326,11 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { value -= seqChannel->soundScriptIO[loBits]; break; -#if !defined(VERSION_SH) && !defined(VERSION_CN) -#ifdef VERSION_EU - // sh: 0x00 - case 0x60: // chan_delayshort - seqChannel->delay = loBits; - goto out; -#endif - - case 0x90: // chan_setlayer - sp5A = m64_read_s16(state); - if (seq_channel_set_layer(seqChannel, loBits) == 0) { -#ifdef VERSION_EU - if (1) {} -#endif - seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; - } - break; - - case 0xa0: // chan_freelayer - seq_channel_layer_free(seqChannel, loBits); - break; - - case 0xb0: // chan_dynsetlayer - if (value != -1 && seq_channel_set_layer(seqChannel, loBits) != -1) { - seqData = (*seqChannel->dynTable)[value]; - sp5A = ((seqData[0] << 8) + seqData[1]); - seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; - } - break; - -#ifndef VERSION_EU - case 0x60: // chan_setnotepriority (arg must be >= 2) - seqChannel->notePriority = loBits; - break; -#endif -#endif - -#if defined(VERSION_SH) || defined(VERSION_CN) case 0x20: -#else - case 0x10: // chan_startchannel -#endif sp5A = m64_read_s16(state); sequence_channel_enable(seqPlayer, loBits, seqPlayer->seqData + sp5A); break; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - case 0x20: // chan_disablechannel - sequence_channel_disable(seqPlayer->channels[loBits]); - break; -#endif - case 0x30: // chan_iowriteval2; write data back to audio lib for another channel cmd = m64_read_u8(state); seqPlayer->channels[loBits]->soundScriptIO[cmd] = value; @@ -2212,15 +1341,11 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { value = seqPlayer->channels[loBits]->soundScriptIO[cmd]; break; } -#if defined(VERSION_SH) || defined(VERSION_CN) } -#endif } } } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) out: -#endif for (i = 0; i < LAYERS_MAX; i++) { if (seqChannel->layers[i] != 0) { @@ -2231,9 +1356,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { u8 cmd; -#if defined(VERSION_SH) || defined(VERSION_CN) UNUSED u32 pad; -#endif u8 loBits; u8 temp; s32 value; @@ -2241,84 +1364,16 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { u16 u16v; u8 *seqData; struct M64ScriptState *state; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) s32 temp32; -#endif if (seqPlayer->enabled == FALSE) { return; } -#if !defined(VERSION_SH) && !defined(VERSION_CN) - if (seqPlayer->bankDmaInProgress == TRUE) { -#ifdef VERSION_EU - if (osRecvMesg(&seqPlayer->bankDmaMesgQueue, NULL, 0) == -1) { - return; - } - if (seqPlayer->bankDmaRemaining == 0) { - seqPlayer->bankDmaInProgress = FALSE; - patch_audio_bank( - (struct AudioBank *) (gCtlEntries[seqPlayer->loadingBankId].instruments - 1), - gAlTbl->seqArray[seqPlayer->loadingBankId].offset, - gCtlEntries[seqPlayer->loadingBankId].numInstruments, - gCtlEntries[seqPlayer->loadingBankId].numDrums); - gCtlEntries[seqPlayer->loadingBankId].drums = - ((struct AudioBank *) (gCtlEntries[seqPlayer->loadingBankId].instruments - 1))->drums; - gBankLoadStatus[seqPlayer->loadingBankId] = SOUND_LOAD_STATUS_COMPLETE; - } else { - audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, - &seqPlayer->bankDmaRemaining, &seqPlayer->bankDmaMesgQueue, - &seqPlayer->bankDmaIoMesg); - } -#else - if (seqPlayer->bankDmaMesg == NULL) { - return; - } - if (seqPlayer->bankDmaRemaining == 0) { - seqPlayer->bankDmaInProgress = FALSE; - patch_audio_bank(seqPlayer->loadingBank, gAlTbl->seqArray[seqPlayer->loadingBankId].offset, - seqPlayer->loadingBankNumInstruments, seqPlayer->loadingBankNumDrums); - gCtlEntries[seqPlayer->loadingBankId].numInstruments = seqPlayer->loadingBankNumInstruments; - gCtlEntries[seqPlayer->loadingBankId].numDrums = seqPlayer->loadingBankNumDrums; - gCtlEntries[seqPlayer->loadingBankId].instruments = seqPlayer->loadingBank->instruments; - gCtlEntries[seqPlayer->loadingBankId].drums = seqPlayer->loadingBank->drums; - gBankLoadStatus[seqPlayer->loadingBankId] = SOUND_LOAD_STATUS_COMPLETE; - } else { - osCreateMesgQueue(&seqPlayer->bankDmaMesgQueue, &seqPlayer->bankDmaMesg, 1); - seqPlayer->bankDmaMesg = NULL; - audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, - &seqPlayer->bankDmaRemaining, &seqPlayer->bankDmaMesgQueue, - &seqPlayer->bankDmaIoMesg); - } -#endif - return; - } - - if (seqPlayer->seqDmaInProgress == TRUE) { -#ifdef VERSION_EU - if (osRecvMesg(&seqPlayer->seqDmaMesgQueue, NULL, 0) == -1) { - return; - } -#ifndef AVOID_UB - if (temp) { - } -#endif -#else - if (seqPlayer->seqDmaMesg == NULL) { - return; - } -#endif - seqPlayer->seqDmaInProgress = FALSE; - gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; - } -#endif - // If discarded, bail out. if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) == FALSE || ( -#if defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->defaultBank[0] != 0xff && -#endif IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) == FALSE)) { eu_stubbed_printf_1("Disappear Sequence or Bank %d\n", seqPlayer->seqId); sequence_player_disable(seqPlayer); @@ -2326,14 +1381,10 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { } // Remove possible SOUND_LOAD_STATUS_DISCARDABLE marks. -#if defined(VERSION_SH) || defined(VERSION_CN) if (gSeqLoadStatus[seqPlayer->seqId] != 5) -#endif gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; -#if defined(VERSION_SH) || defined(VERSION_CN) if (gBankLoadStatus[seqPlayer->defaultBank[0]] != 5) -#endif gBankLoadStatus[seqPlayer->defaultBank[0]] = SOUND_LOAD_STATUS_COMPLETE; if (seqPlayer->muted && (seqPlayer->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT) != 0) { @@ -2342,9 +1393,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { // Check if we surpass the number of ticks needed for a tatum, else stop. seqPlayer->tempoAcc += seqPlayer->tempo; -#if defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->tempoAcc += seqPlayer->tempoAdd; -#endif if (seqPlayer->tempoAcc < gTempoInternalToExternal) { return; } @@ -2358,9 +1407,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { #endif seqPlayer->delay--; } else { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->recalculateVolume = 1; -#endif for (;;) { cmd = m64_read_u8(state); if (cmd == 0xff) { // seq_end @@ -2368,11 +1415,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { sequence_player_disable(seqPlayer); break; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) state->pc = state->stack[--state->depth]; -#else - state->depth--, state->pc = state->stack[state->depth]; -#endif } if (cmd == 0xfd) { // seq_delay @@ -2395,11 +1438,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { if (0 && state->depth >= 4) { eu_stubbed_printf_0("Macro Level Over Error!\n"); } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) state->stack[state->depth++] = state->pc; -#else - state->depth++, state->stack[state->depth - 1] = state->pc; -#endif state->pc = seqPlayer->seqData + u16v; break; @@ -2408,11 +1447,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { eu_stubbed_printf_0("Macro Level Over Error!\n"); } state->remLoopIters[state->depth] = m64_read_u8(state); -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) state->stack[state->depth++] = state->pc; -#else - state->depth++, state->stack[state->depth - 1] = state->pc; -#endif break; case 0xf7: // seq_loopend @@ -2441,7 +1476,6 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { state->pc = seqPlayer->seqData + u16v; break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xf4: case 0xf3: case 0xf2: @@ -2454,22 +1488,13 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { } state->pc += (s8) temp; break; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xf1: // seq_reservenotes -#else - case 0xf2: // seq_reservenotes -#endif note_pool_clear(&seqPlayer->notePool); note_pool_fill(&seqPlayer->notePool, m64_read_u8(state)); break; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xf0: // seq_unreservenotes -#else - case 0xf1: // seq_unreservenotes -#endif note_pool_clear(&seqPlayer->notePool); break; @@ -2482,19 +1507,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { break; case 0xdd: // seq_settempo (bpm) -#if !defined(VERSION_SH) && !defined(VERSION_CN) - case 0xdc: // seq_addtempo (bpm) -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->tempo = m64_read_u8(state) * TEMPO_SCALE; -#else - temp = m64_read_u8(state); - if (cmd == 0xdd) { - seqPlayer->tempo = temp * TEMPO_SCALE; - } else { - seqPlayer->tempo += (s8) temp * TEMPO_SCALE; - } -#endif if (seqPlayer->tempo > gTempoInternalToExternal) { seqPlayer->tempo = gTempoInternalToExternal; @@ -2507,13 +1520,10 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { } break; -#if defined(VERSION_SH) || defined(VERSION_CN) case 0xdc: // seq_addtempo (bpm) seqPlayer->tempoAdd = (s8) m64_read_u8(state) * TEMPO_SCALE; break; -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xda: cmd = m64_read_u8(state); u16v = m64_read_s16(state); @@ -2552,41 +1562,11 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { } } break; -#else - case 0xdb: // seq_setvol - cmd = m64_read_u8(state); - switch (seqPlayer->state) { - case SEQUENCE_PLAYER_STATE_2: - if (seqPlayer->fadeRemainingFrames != 0) { - f32 targetVolume = FLOAT_CAST(cmd) / US_FLOAT(127.0); - seqPlayer->fadeVelocity = (targetVolume - seqPlayer->fadeVolume) - / FLOAT_CAST(seqPlayer->fadeRemainingFrames); - break; - } - // fallthrough - case SEQUENCE_PLAYER_STATE_0: - seqPlayer->fadeVolume = FLOAT_CAST(cmd) / US_FLOAT(127.0); - break; - case SEQUENCE_PLAYER_STATE_FADE_OUT: - case SEQUENCE_PLAYER_STATE_4: - seqPlayer->volume = FLOAT_CAST(cmd) / US_FLOAT(127.0); - break; - } - break; - case 0xda: // seq_changevol - temp = m64_read_u8(state); - seqPlayer->fadeVolume = - seqPlayer->fadeVolume + (f32)(s8) temp / US_FLOAT(127.0); - break; -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) case 0xd9: temp = m64_read_u8(state); seqPlayer->fadeVolumeScale = (s8) temp / 127.0f; break; -#endif case 0xd7: // seq_initchannels u16v = m64_read_s16(state); @@ -2600,7 +1580,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { case 0xd5: // seq_setmutescale temp = m64_read_u8(state); - seqPlayer->muteVolumeScale = (f32)(s8) temp / US_FLOAT(127.0); + seqPlayer->muteVolumeScale = (f32)(s8) temp / 127.0f; break; case 0xd4: // seq_mute @@ -2631,18 +1611,13 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { break; case 0xc9: // seq_bitand -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) value &= m64_read_u8(state); -#else - value = m64_read_u8(state) & value; -#endif break; case 0xc8: // seq_subtract value = value - m64_read_u8(state); break; -#if defined(VERSION_SH) || defined(VERSION_CN) case 0xc7: cmd = m64_read_u8(state); u16v = m64_read_s16(state); @@ -2653,7 +1628,6 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { case 0xc6: seqPlayer->unkSh = TRUE; return; -#endif default: eu_stubbed_printf_1("Group:Undefine upper C0h command (%x)\n", cmd); @@ -2663,13 +1637,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { loBits = cmd & 0xf; switch (cmd & 0xf0) { case 0x00: // seq_testchdisabled -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) value = seqPlayer->channels[loBits]->finished; -#else - if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[loBits]) == TRUE) { - value = seqPlayer->channels[loBits]->finished; - } -#endif break; case 0x10: break; @@ -2678,27 +1646,15 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { case 0x40: break; case 0x50: // seq_subvariation -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) value -= seqPlayer->seqVariationEu[0]; -#else - value -= seqPlayer->seqVariation; -#endif break; case 0x60: break; case 0x70: // seq_setvariation -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->seqVariationEu[0] = value; -#else - seqPlayer->seqVariation = value; -#endif break; case 0x80: // seq_getvariation -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) value = seqPlayer->seqVariationEu[0]; -#else - value = seqPlayer->seqVariation; -#endif break; case 0x90: // seq_startchannel u16v = m64_read_s16(state); @@ -2706,12 +1662,6 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { break; case 0xa0: break; -#if defined(VERSION_JP) || defined(VERSION_US) - case 0xd8: // (this makes no sense) - break; - case 0xd9: - break; -#endif default: eu_stubbed_printf_0("Group:Undefined Command\n"); @@ -2722,15 +1672,9 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { } for (i = 0; i < CHANNELS_MAX; i++) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE) { sequence_channel_process_script(seqPlayer->channels[i]); } -#else - if (seqPlayer->channels[i] != &gSequenceChannelNone) { - sequence_channel_process_script(seqPlayer->channels[i]); - } -#endif } } @@ -2739,57 +1683,30 @@ void process_sequences(UNUSED s32 iterationsRemaining) { s32 i; for (i = 0; i < SEQUENCE_PLAYERS; i++) { if (gSequencePlayers[i].enabled == TRUE) { -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) sequence_player_process_sequence(&gSequencePlayers[i]); sequence_player_process_sound(&gSequencePlayers[i]); -#else - sequence_player_process_sequence(gSequencePlayers + i); - sequence_player_process_sound(gSequencePlayers + i); -#endif } } -#if defined(VERSION_JP) || defined(VERSION_US) - reclaim_notes(); -#endif process_notes(); } void init_sequence_player(u32 player) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) sequence_player_disable(seqPlayer); -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->unkSh = FALSE; -#else - seqPlayer->muted = FALSE; -#endif seqPlayer->delay = 0; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->state = 1; -#else - seqPlayer->state = SEQUENCE_PLAYER_STATE_0; -#endif seqPlayer->fadeRemainingFrames = 0; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->fadeTimerUnkEu = 0; -#endif seqPlayer->tempoAcc = 0; seqPlayer->tempo = 120 * TEMPO_SCALE; // 120 BPM -#if defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->tempoAdd = 0; -#endif seqPlayer->transposition = 0; -#if !defined(VERSION_SH) && !defined(VERSION_CN) - seqPlayer->muteBehavior = MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_SOFTEN; -#endif seqPlayer->noteAllocPolicy = 0; seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; seqPlayer->shortNoteDurationTable = gDefaultShortNoteDurationTable; seqPlayer->fadeVolume = 1.0f; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) seqPlayer->fadeVolumeScale = 1.0f; -#endif seqPlayer->fadeVelocity = 0.0f; seqPlayer->volume = 0.0f; seqPlayer->muteVolumeScale = 0.5f; @@ -2802,11 +1719,6 @@ void init_sequence_players(void) { for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { gSequenceChannels[i].seqPlayer = NULL; gSequenceChannels[i].enabled = FALSE; -#if defined(VERSION_JP) || defined(VERSION_US) - } - - for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { -#endif // @bug Size of wrong array. Zeroes out second half of gSequenceChannels[0], // all of gSequenceChannels[1..31], and part of gSequenceLayers[0]. // However, this is only called at startup, so it's harmless. @@ -2832,16 +1744,10 @@ void init_sequence_players(void) { gSequencePlayers[i].channels[j] = &gSequenceChannelNone; } -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) gSequencePlayers[i].seqVariationEu[0] = -1; -#else - gSequencePlayers[i].seqVariation = -1; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) gSequencePlayers[i].muteBehavior = MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_SOFTEN; gSequencePlayers[i].enabled = FALSE; gSequencePlayers[i].muted = FALSE; -#endif gSequencePlayers[i].bankDmaInProgress = FALSE; gSequencePlayers[i].seqDmaInProgress = FALSE; init_note_lists(&gSequencePlayers[i].notePool); diff --git a/src/audio/sh/seqplayer.h b/src/audio/sh/seqplayer.h new file mode 100644 index 00000000..d2fc1344 --- /dev/null +++ b/src/audio/sh/seqplayer.h @@ -0,0 +1,18 @@ +#ifndef AUDIO_SEQPLAYER_H +#define AUDIO_SEQPLAYER_H + +#include + +#include "internal.h" +#include "playback.h" + +void seq_channel_layer_disable(struct SequenceChannelLayer *seqPlayer); +void sequence_channel_disable(struct SequenceChannel *seqPlayer); +void sequence_player_disable(struct SequencePlayer* seqPlayer); +void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item); +void *audio_list_pop_back(struct AudioListItem *list); +void process_sequences(s32 iterationsRemaining); +void init_sequence_player(u32 player); +void init_sequence_players(void); + +#endif // AUDIO_SEQPLAYER_H diff --git a/src/audio/synthesis_sh.c b/src/audio/sh/synthesis.c similarity index 96% rename from src/audio/synthesis_sh.c rename to src/audio/sh/synthesis.c index 66759cbf..ade77675 100644 --- a/src/audio/synthesis_sh.c +++ b/src/audio/sh/synthesis.c @@ -1,4 +1,3 @@ -#if defined(VERSION_SH) || defined(VERSION_CN) #include #include "synthesis.h" @@ -7,7 +6,6 @@ #include "load.h" #include "seqplayer.h" #include "internal.h" -#include "external.h" #define DMEM_ADDR_TEMP 0x450 @@ -383,54 +381,54 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { UNUSED s32 pad0[3]; - struct AudioBankSample *audioBookSample; // sp164, sp138 - struct AdpcmLoop *loopInfo; // sp160, sp134 - s16 *curLoadedBook; // sp154, sp130 + struct AudioBankSample *audioBookSample; + struct AdpcmLoop *loopInfo; + s16 *curLoadedBook; UNUSED u8 padEU[0x04]; UNUSED u8 pad8[0x04]; - s32 noteFinished; // 150 t2, sp124 - s32 restart; // 14c t3, sp120 - s32 flags; // sp148, sp11C, t8 - u16 resamplingRateFixedPoint; // sp5c, sp11A - s32 nSamplesToLoad; //s0, Ec - UNUSED u8 pad7[0x0c]; // sp100 - s32 sp130; //sp128, sp104 + s32 noteFinished; + s32 restart; + s32 flags; + u16 resamplingRateFixedPoint; + s32 nSamplesToLoad; + UNUSED u8 pad7[0x0c]; + s32 sp130; UNUSED s32 tempBufLen; UNUSED u32 pad9; s32 t0; - u8 *sampleAddr; // sp120, spF4 + u8 *sampleAddr; s32 s6; - s32 samplesLenAdjusted; // 108, spEC - s32 nAdpcmSamplesProcessed; // signed required for US // spc0 - s32 endPos; // sp110, spE4 - s32 nSamplesToProcess; // sp10c/a0, spE0 + s32 samplesLenAdjusted; + s32 nAdpcmSamplesProcessed; + s32 endPos; + s32 nSamplesToProcess; // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange // behavior with the break near the end of the loop, causing US and JP to need a goto instead UNUSED s32 samplesLenInt; s32 s2; - s32 leftRight; //s0 - s32 s5; //s4 - u32 samplesLenFixedPoint; // v1_1 - s32 s3; // spA0 - s32 nSamplesInThisIteration; // v1_2 + s32 leftRight; + s32 s5; + u32 samplesLenFixedPoint; + s32 s3; + s32 nSamplesInThisIteration; u32 a3; u8 *v0_2; - s32 unk_s6; // sp90 + s32 unk_s6; s32 s5Aligned; s32 sp88; s32 sp84; u32 temp; - s32 nParts; // spE8, spBC - s32 curPart; // spE4, spB8 + s32 nParts; + s32 curPart; s32 aligned; UNUSED u32 padSH1; - s32 resampledTempLen; // spD8, spAC, sp6c - u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA, sp6a -- 6C + s32 resampledTempLen; + u16 noteSamplesDmemAddrBeforeResampling; UNUSED u32 padSH2; UNUSED u32 padSH3; UNUSED u32 padSH4; - struct Note *note; // sp58 - u16 sp56; // sp56 + struct Note *note; + u16 sp56; u16 addr; u8 synthesisVolume; @@ -482,8 +480,8 @@ u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct N sampleAddr = audioBookSample->sampleAddr; resampledTempLen = 0; for (curPart = 0; curPart < nParts; curPart++) { - nAdpcmSamplesProcessed = 0; // s8 - s5 = 0; // s4 + nAdpcmSamplesProcessed = 0; + s5 = 0; if (nParts == 1) { samplesLenAdjusted = nSamplesToLoad; @@ -514,7 +512,7 @@ u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct N } while (nAdpcmSamplesProcessed != samplesLenAdjusted) { - s32 samplesRemaining; // v1 + s32 samplesRemaining; s32 s0; noteFinished = FALSE; @@ -526,7 +524,7 @@ u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct N if (s2 == 0 && synthesisState->restart == FALSE) { s2 = 16; } - s6 = 16 - s2; // a1 + s6 = 16 - s2; if (nSamplesToProcess < samplesRemaining) { t0 = (nSamplesToProcess - s6 + 0xf) / 16; s0 = t0 * 16; @@ -690,7 +688,6 @@ skip: if (noteSubEu->filter) { aFilter(cmd++, 0x02, bufLen * 2, noteSubEu->filter); aFilter(cmd++, flags, DMEM_ADDR_TEMP, synthesisState->synthesisBuffers->filterBuffer); - } if (noteSubEu->bookOffset == 3) { @@ -907,4 +904,3 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struc return cmd; } -#endif diff --git a/src/audio/synthesis.h b/src/audio/sh/synthesis.h similarity index 69% rename from src/audio/synthesis.h rename to src/audio/sh/synthesis.h index 1f1fb9b0..67afbe94 100644 --- a/src/audio/synthesis.h +++ b/src/audio/sh/synthesis.h @@ -3,19 +3,10 @@ #include "internal.h" -#if defined(VERSION_SH) || defined(VERSION_CN) #define DEFAULT_LEN_1CH 0x180 #define DEFAULT_LEN_2CH 0x300 -#else -#define DEFAULT_LEN_1CH 0x140 -#define DEFAULT_LEN_2CH 0x280 -#endif -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) #define MAX_UPDATES_PER_FRAME 5 -#else -#define MAX_UPDATES_PER_FRAME 4 -#endif struct ReverbRingBufferItem { s16 numSamplesAfterDownsampling; @@ -32,22 +23,14 @@ struct SynthesisReverb { /*0x01, 0x01, 0x01*/ u8 useReverb; /*0x02, 0x02, 0x02*/ u8 framesLeftToIgnore; /*0x03, 0x03, 0x03*/ u8 curFrame; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) /* 0x04, 0x04*/ u8 downsampleRate; -#if defined(VERSION_SH) || defined(VERSION_CN) /* 0x05*/ s8 unk5; -#endif /* 0x06, 0x06*/ u16 windowSize; // same as bufSizePerChannel -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) /* 0x08*/ u16 unk08; -#endif /*0x04, 0x08, 0x0A*/ u16 reverbGain; /*0x06, 0x0A, 0x0C*/ u16 resampleRate; -#if defined(VERSION_SH) || defined(VERSION_CN) /* 0x0E*/ u16 panRight; /* 0x10*/ u16 panLeft; -#endif /*0x08, 0x0C, 0x14*/ s32 nextRingBufferPos; /*0x0C, 0x10, 0x18*/ s32 unkC; // never read /*0x10, 0x14, 0x1C*/ s32 bufSizePerChannel; @@ -60,15 +43,12 @@ struct SynthesisReverb { /*0x24, 0x28, 0x30*/ s16 *unk24; // never read /*0x28, 0x2C, 0x34*/ s16 *unk28; // never read /*0x2C, 0x30, 0x38*/ struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME]; -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) // Only used in sh: /* 0x100*/ s16 *unk100; /* 0x104*/ s16 *unk104; /* 0x108*/ s16 *unk108; /* 0x10C*/ s16 *unk10C; -#endif }; // 0xCC <= size <= 0x100 -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) extern struct SynthesisReverb gSynthesisReverbs[4]; extern s8 gNumSynthesisReverbs; extern struct NoteSubEu *gNoteSubsEu; @@ -76,21 +56,9 @@ extern f32 gLeftVolRampings[3][1024]; extern f32 gRightVolRampings[3][1024]; extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above -#else -extern struct SynthesisReverb gSynthesisReverb; -#endif -#if defined(VERSION_SH) || defined(VERSION_CN) extern s16 D_SH_803479B4; -#endif u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen); -#if defined(VERSION_JP) || defined(VERSION_US) -void note_init_volume(struct Note *note); -void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol); -void note_set_frequency(struct Note *note, f32 frequency); -void note_enable(struct Note *note); -void note_disable(struct Note *note); -#endif #endif // AUDIO_SYNTHESIS_H diff --git a/src/audio/us_jp/data.c b/src/audio/us_jp/data.c new file mode 100644 index 00000000..7ff7f158 --- /dev/null +++ b/src/audio/us_jp/data.c @@ -0,0 +1,402 @@ +#include + +#include "data.h" +#include "effects.h" + +extern struct OSMesgQueue OSMesgQueue0; +extern struct OSMesgQueue OSMesgQueue1; +extern struct OSMesgQueue OSMesgQueue2; +extern struct OSMesgQueue OSMesgQueue3; + +// Format: +// - frequency +// - max number of simultaneous notes +// - reverb downsample rate (makes the ring buffer be downsampled to save memory) +// - reverb window size (ring buffer size, length affects reverb delay) +// - reverb gain (0 = min reverb, 32767 = max reverb, 32769 to 65535 = louder and louder...) +// - volume +// - memory used for persistent sequences +// - memory used for persistent banks +// - memory used for temporary sequences +// - memory used for temporary banks +struct AudioSessionSettings gAudioSessionPresets[18] = { +#ifdef VERSION_JP + { 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0E00, 0x3FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3E00, 0x6200, 0x3F00, 0x2A00 }, + { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3F00, 0x6200, 0x4400, 0x2A80 }, + { 32000, 20, 1, 0x0800, 0x37FF, 0x7FFF, 0x3300, 0x5500, 0x4000, 0x1B00 }, +#else + { 32000, 16, 1, 0x0C00, 0x2FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0E00, 0x3FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x3A00, 0x6D00, 0x4400, 0x2A00 }, + { 32000, 16, 1, 0x0C00, 0x2FFF, 0x7FFF, 0x4000, 0x6E00, 0x3F00, 0x2A00 }, + { 32000, 16, 1, 0x0A00, 0x47FF, 0x7FFF, 0x4100, 0x6E00, 0x4400, 0x2A80 }, + { 32000, 20, 1, 0x0800, 0x37FF, 0x7FFF, 0x34C0, 0x6280, 0x4000, 0x1B00 }, +#endif + { 27000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 27000, 16, 1, 0x0800, 0x3FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 27000, 16, 1, 0x1000, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 27000, 16, 1, 0x1000, 0x3FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 27000, 16, 1, 0x0C00, 0x4FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 32000, 14, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 32000, 12, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 32000, 10, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 32000, 8, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; +// gAudioCosineTable[k] = round((2**15 - 1) * cos(pi/2 * k / 127)). Unused. +u16 gAudioCosineTable[128] = { + 0x7FFF, 32764, 32757, 32744, 32727, 32704, 32677, 32644, 32607, 32564, 32517, 32464, 32407, + 32344, 32277, 32205, 32127, 32045, 31958, 31866, 31770, 31668, 31561, 31450, 31334, 31213, + 31087, 30957, 30822, 30682, 30537, 30388, 30234, 30075, 29912, 29744, 29572, 29395, 29214, + 29028, 28838, 28643, 28444, 28241, 28033, 27821, 27605, 27385, 27160, 26931, 26698, 26461, + 26220, 25975, 25726, 25473, 25216, 24956, 24691, 24423, 24151, 23875, 23596, 23313, 23026, + 22736, 22442, 22145, 21845, 21541, 21234, 20924, 20610, 20294, 19974, 19651, 19325, 18997, + 18665, 18331, 17993, 17653, 17310, 16965, 16617, 16266, 15913, 15558, 15200, 14840, 14477, + 14113, 13746, 13377, 13006, 12633, 12258, 11881, 11503, 11122, 10740, 10357, 9971, 9584, + 9196, 8806, 8415, 8023, 7630, 7235, 6839, 6442, 6044, 5646, 5246, 4845, 4444, + 4042, 3640, 3237, 2833, 2429, 2025, 1620, 1216, 810, 405, 0, +}; + +// Transforms a pitch scale factor in -127..127 into a frequency scale factor +// between -1 and +1 octave. +// gPitchBendFrequencyScale[k] = 0.5 * 2^(k/127) +f32 gPitchBendFrequencyScale[255] = { + 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f, + 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, + 0.551614f, 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, + 0.579387f, 0.582558f, 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.601950f, 0.605245f, + 0.608557f, 0.611888f, 0.615236f, 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f, + 0.639196f, 0.642694f, 0.646212f, 0.649748f, 0.653304f, 0.656880f, 0.660475f, 0.664089f, 0.667724f, + 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, 0.689952f, 0.693727f, 0.697524f, 0.701341f, + 0.705180f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, 0.728655f, 0.732642f, 0.736652f, + 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.765340f, 0.769529f, 0.773740f, + 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f, 0.812696f, + 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.839750f, 0.844346f, 0.848966f, 0.853613f, + 0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.896590f, + 0.901496f, 0.906430f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.941730f, + 0.946884f, 0.952066f, 0.957277f, 0.962516f, 0.967783f, 0.973080f, 0.978405f, 0.983760f, 0.989144f, + 0.994557f, 1.0f, 1.005473f, 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f, + 1.044630f, 1.050347f, 1.056095f, 1.061875f, 1.067687f, 1.073530f, 1.079405f, 1.085312f, 1.091252f, + 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, 1.127579f, 1.133750f, 1.139955f, 1.146193f, + 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, 1.190831f, 1.197348f, 1.203901f, + 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, 1.257631f, 1.264514f, + 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f, 1.328178f, + 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f, + 1.402683f, 1.410360f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f, + 1.473304f, 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f, + 1.547481f, 1.555950f, 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f, + 1.625392f, 1.634287f, 1.643231f, 1.652224f, 1.661266f, 1.670358f, 1.679500f, 1.688691f, 1.697933f, + 1.707225f, 1.716569f, 1.725963f, 1.735409f, 1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f, + 1.793179f, 1.802993f, 1.812860f, 1.822782f, 1.832757f, 1.842788f, 1.852873f, 1.863013f, 1.873209f, + 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, 1.946159f, 1.956810f, 1.967520f, + 1.978287f, 1.989114f, 2.0f +}; + +// Frequencies for notes using the standard twelve-tone equal temperament scale. +// For indices 0..116, gNoteFrequencies[k] = 2^((k-39)/12). +// For indices 117..128, gNoteFrequencies[k] = 0.5 * 2^((k-39)/12). +// The 39 in the formula refers to piano key 40 (middle C, at 256 Hz) being +// the reference frequency, which is assigned value 1. +// clang-format off +f32 gNoteFrequencies[128] = { + 0.105112f, 0.111362f, 0.117984f, 0.125f, 0.132433f, 0.140308f, 0.148651f, 0.15749f, 0.166855f, 0.176777f, 0.187288f, 0.198425f, + 0.210224f, 0.222725f, 0.235969f, 0.25f, 0.264866f, 0.280616f, 0.297302f, 0.31498f, 0.33371f, 0.353553f, 0.374577f, 0.39685f, + 0.420448f, 0.445449f, 0.471937f, 0.5f, 0.529732f, 0.561231f, 0.594604f, 0.629961f, 0.66742f, 0.707107f, 0.749154f, 0.793701f, + 0.840897f, 0.890899f, 0.943875f, 1.0f, 1.059463f, 1.122462f, 1.189207f, 1.259921f, 1.33484f, 1.414214f, 1.498307f, 1.587401f, + 1.681793f, 1.781798f, 1.887749f, 2.0f, 2.118926f, 2.244924f, 2.378414f, 2.519842f, 2.66968f, 2.828428f, 2.996615f, 3.174803f, + 3.363586f, 3.563596f, 3.775498f, 4.0f, 4.237853f, 4.489849f, 4.756829f, 5.039685f, 5.33936f, 5.656855f, 5.993229f, 6.349606f, + 6.727173f, 7.127192f, 7.550996f, 8.0f, 8.475705f, 8.979697f, 9.513658f, 10.07937f, 10.67872f, 11.31371f, 11.986459f, 12.699211f, + 13.454346f, 14.254383f, 15.101993f, 16.0f, 16.95141f, 17.959394f, 19.027315f, 20.15874f, 21.35744f, 22.62742f, 23.972918f, 25.398422f, + 26.908691f, 28.508766f, 30.203985f, 32.0f, 33.90282f, 35.91879f, 38.05463f, 40.31748f, 42.71488f, 45.25484f, 47.945835f, 50.796844f, + 53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f, 85.42976f, 45.25484f, 47.945835f, 50.796844f, + 53.817383f, 57.017532f, 60.40797f, 64.0f, 67.80564f, 71.83758f, 76.10926f, 80.63496f +}; +// clang-format on + +// goes up by ~12 at each step for the first 4 values (starting from 0), then by ~6 +u8 gDefaultShortNoteVelocityTable[16] = { + 12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127, +}; + +// goes down by 26 at each step for the first 4 values (starting from 255), then by ~12 +u8 gDefaultShortNoteDurationTable[16] = { + 229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0, +}; + +// gVibratoCurve[k] = k*8 +s8 gVibratoCurve[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; + +struct AdsrEnvelope gDefaultEnvelope[] = { + { BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms + { BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds + { BSWAP16(ADSR_HANG), 0 } // then continue staying there +}; + +s16 sSineWave[0x40] = { + 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244, + 28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897, + 27244, 25329, 23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211, 0, + -3211, -6392, -9511, -12539, -15446, -18204, -20787, -23169, -25329, -27244, -28897, + -30272, -31356, -32137, -32609, -0x7FFF, -32609, -32137, -31356, -30272, -28897, -27244, + -25329, -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, +}; + +s16 sSquareWave[0x40] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, + -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +}; +s16 sTriangleWave[0x40] = { + 0, 0x7FF, 0xFFF, 0x17FF, 0x1FFF, 0x27FF, 0x2FFF, 0x37FF, 0x3FFF, 0x47FF, 0x4FFF, + 0x57FF, 0x5FFF, 0x67FF, 0x6FFF, 0x77FF, 0x7FFF, 0x77FF, 0x6FFF, 0x67FF, 0x5FFF, 0x57FF, + 0x4FFF, 0x47FF, 0x3FFF, 0x37FF, 0x2FFF, 0x27FF, 0x1FFF, 0x17FF, 0xFFF, 0x7FF, 0, + -0x7FF, -0xFFF, -0x17FF, -0x1FFF, -10239, -0x2FFF, -0x37FF, -0x3FFF, -0x47FF, -0x4FFF, -22527, + -24575, -26623, -28671, -30719, -0x7FFF, -30719, -28671, -26623, -24575, -22527, -0x4FFF, + -0x47FF, -0x3FFF, -0x37FF, -0x2FFF, -0x27FF, -0x1FFF, -0x17FF, -0xFFF, -0x7FF, +}; + +s16 sSawtoothWave[0x40] = { + 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, + 11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503, + 22527, 23551, 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, -0x7FFF, + -31743, -30719, -29695, -28671, -27647, -26623, -25599, -24575, -23551, -22527, -21503, + -0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239, + -9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, +}; +s16 *gWaveSamples[4] = { sSawtoothWave, sTriangleWave, sSineWave, sSquareWave }; + +u16 gHeadsetPanQuantization[10] = { 0x40, 0x30, 0x20, 0x10, 0, 0, 0, 0, 0, 0 }; + +// Linearly interpolated between +// f(0/2 * 127) = 1 +// f(1/2 * 127) = 1/sqrt(2) +// f(2/2 * 127) = 0 +f32 gHeadsetPanVolume[128] = { + 1.0f, 0.995386f, 0.990772f, 0.986157f, 0.981543f, 0.976929f, 0.972315f, 0.967701f, 0.963087f, + 0.958472f, 0.953858f, 0.949244f, 0.94463f, 0.940016f, 0.935402f, 0.930787f, 0.926173f, 0.921559f, + 0.916945f, 0.912331f, 0.907717f, 0.903102f, 0.898488f, 0.893874f, 0.88926f, 0.884646f, 0.880031f, + 0.875417f, 0.870803f, 0.866189f, 0.861575f, 0.856961f, 0.852346f, 0.847732f, 0.843118f, 0.838504f, + 0.83389f, 0.829276f, 0.824661f, 0.820047f, 0.815433f, 0.810819f, 0.806205f, 0.801591f, 0.796976f, + 0.792362f, 0.787748f, 0.783134f, 0.77852f, 0.773906f, 0.769291f, 0.764677f, 0.760063f, 0.755449f, + 0.750835f, 0.74622f, 0.741606f, 0.736992f, 0.732378f, 0.727764f, 0.72315f, 0.718535f, 0.713921f, + 0.709307f, 0.70537f, 0.70211f, 0.69885f, 0.695591f, 0.692331f, 0.689071f, 0.685811f, 0.682551f, + 0.679291f, 0.676031f, 0.672772f, 0.669512f, 0.666252f, 0.662992f, 0.659732f, 0.656472f, 0.653213f, + 0.649953f, 0.646693f, 0.643433f, 0.640173f, 0.636913f, 0.633654f, 0.630394f, 0.627134f, 0.623874f, + 0.620614f, 0.617354f, 0.614094f, 0.610835f, 0.607575f, 0.604315f, 0.601055f, 0.597795f, 0.594535f, + 0.591276f, 0.588016f, 0.584756f, 0.581496f, 0.578236f, 0.574976f, 0.571717f, 0.568457f, 0.565197f, + 0.561937f, 0.558677f, 0.555417f, 0.552157f, 0.548898f, 0.545638f, 0.542378f, 0.539118f, 0.535858f, + 0.532598f, 0.529339f, 0.526079f, 0.522819f, 0.519559f, 0.516299f, 0.513039f, 0.50978f, 0.50652f, + 0.50326f, 0.5f +}; + +// Linearly interpolated between +// f(0/4 * 127) = 1/sqrt(2) +// f(1/4 * 127) = 1 +// f(2/4 * 127) = 1/sqrt(2) +// f(3/4 * 127) = 0 +// f(4/4 * 127) = 1/sqrt(8) +f32 gStereoPanVolume[128] = { + 0.707f, 0.716228f, 0.725457f, 0.734685f, 0.743913f, 0.753142f, 0.76237f, 0.771598f, 0.780827f, + 0.790055f, 0.799283f, 0.808512f, 0.81774f, 0.826968f, 0.836197f, 0.845425f, 0.854654f, 0.863882f, + 0.87311f, 0.882339f, 0.891567f, 0.900795f, 0.910024f, 0.919252f, 0.92848f, 0.937709f, 0.946937f, + 0.956165f, 0.965394f, 0.974622f, 0.98385f, 0.993079f, 0.997693f, 0.988465f, 0.979236f, 0.970008f, + 0.960779f, 0.951551f, 0.942323f, 0.933095f, 0.923866f, 0.914638f, 0.905409f, 0.896181f, 0.886953f, + 0.877724f, 0.868496f, 0.859268f, 0.850039f, 0.840811f, 0.831583f, 0.822354f, 0.813126f, 0.803898f, + 0.794669f, 0.785441f, 0.776213f, 0.766984f, 0.757756f, 0.748528f, 0.739299f, 0.730071f, 0.720843f, + 0.711614f, 0.695866f, 0.673598f, 0.651331f, 0.629063f, 0.606795f, 0.584528f, 0.56226f, 0.539992f, + 0.517724f, 0.495457f, 0.473189f, 0.450921f, 0.428654f, 0.406386f, 0.384118f, 0.36185f, 0.339583f, + 0.317315f, 0.295047f, 0.27278f, 0.250512f, 0.228244f, 0.205976f, 0.183709f, 0.161441f, 0.139173f, + 0.116905f, 0.094638f, 0.07237f, 0.050102f, 0.027835f, 0.005567f, 0.00835f, 0.019484f, 0.030618f, + 0.041752f, 0.052886f, 0.06402f, 0.075154f, 0.086287f, 0.097421f, 0.108555f, 0.119689f, 0.130823f, + 0.141957f, 0.153091f, 0.164224f, 0.175358f, 0.186492f, 0.197626f, 0.20876f, 0.219894f, 0.231028f, + 0.242161f, 0.253295f, 0.264429f, 0.275563f, 0.286697f, 0.297831f, 0.308965f, 0.320098f, 0.331232f, + 0.342366f, 0.3535f +}; + +// gDefaultVolume[k] = cos(pi/2 * k / 127) +f32 gDefaultPanVolume[128] = { + 1.0f, 0.999924f, 0.999694f, 0.999312f, 0.998776f, 0.998088f, 0.997248f, 0.996254f, 0.995109f, + 0.993811f, 0.992361f, 0.990759f, 0.989006f, 0.987101f, 0.985045f, 0.982839f, 0.980482f, 0.977976f, + 0.97532f, 0.972514f, 0.96956f, 0.966457f, 0.963207f, 0.959809f, 0.956265f, 0.952574f, 0.948737f, + 0.944755f, 0.940629f, 0.936359f, 0.931946f, 0.92739f, 0.922692f, 0.917853f, 0.912873f, 0.907754f, + 0.902497f, 0.897101f, 0.891567f, 0.885898f, 0.880093f, 0.874153f, 0.868079f, 0.861873f, 0.855535f, + 0.849066f, 0.842467f, 0.835739f, 0.828884f, 0.821901f, 0.814793f, 0.807561f, 0.800204f, 0.792725f, + 0.785125f, 0.777405f, 0.769566f, 0.76161f, 0.753536f, 0.745348f, 0.737045f, 0.72863f, 0.720103f, + 0.711466f, 0.70272f, 0.693867f, 0.684908f, 0.675843f, 0.666676f, 0.657406f, 0.648036f, 0.638567f, + 0.629f, 0.619337f, 0.609579f, 0.599728f, 0.589785f, 0.579752f, 0.56963f, 0.559421f, 0.549126f, + 0.538748f, 0.528287f, 0.517745f, 0.507124f, 0.496425f, 0.485651f, 0.474802f, 0.46388f, 0.452888f, + 0.441826f, 0.430697f, 0.419502f, 0.408243f, 0.396921f, 0.385538f, 0.374097f, 0.362598f, 0.351044f, + 0.339436f, 0.327776f, 0.316066f, 0.304308f, 0.292503f, 0.280653f, 0.268761f, 0.256827f, 0.244854f, + 0.232844f, 0.220798f, 0.208718f, 0.196606f, 0.184465f, 0.172295f, 0.160098f, 0.147877f, 0.135634f, + 0.12337f, 0.111087f, 0.098786f, 0.086471f, 0.074143f, 0.061803f, 0.049454f, 0.037097f, 0.024734f, + 0.012368f, 0.0f +}; + +// gVolRampingLhs136[k] = 2^16 * max(1, (256*k)^(1/17) +f32 gVolRampingLhs136[128] = { + 65536.0f, 90811.555f, 94590.766f, 96873.96f, 98527.26f, 99829.06f, 100905.47f, + 101824.61f, 102627.57f, 103341.086f, 103983.55f, 104568.164f, 105104.75f, 105600.8f, + 106062.14f, 106493.46f, 106898.52f, 107280.414f, 107641.73f, 107984.62f, 108310.93f, + 108622.23f, 108919.875f, 109205.055f, 109478.8f, 109742.0f, 109995.48f, 110239.94f, + 110476.02f, 110704.305f, 110925.3f, 111139.45f, 111347.21f, 111548.945f, 111745.0f, + 111935.7f, 112121.35f, 112302.2f, 112478.51f, 112650.51f, 112818.4f, 112982.38f, + 113142.66f, 113299.37f, 113452.69f, 113602.766f, 113749.734f, 113893.73f, 114034.87f, + 114173.26f, 114309.02f, 114442.26f, 114573.055f, 114701.5f, 114827.69f, 114951.695f, + 115073.6f, 115193.47f, 115311.375f, 115427.39f, 115541.56f, 115653.96f, 115764.63f, + 115873.64f, 115981.04f, 116086.86f, 116191.164f, 116293.99f, 116395.38f, 116495.38f, + 116594.02f, 116691.34f, 116787.39f, 116882.19f, 116975.77f, 117068.17f, 117159.414f, + 117249.54f, 117338.57f, 117426.53f, 117513.45f, 117599.35f, 117684.266f, 117768.2f, + 117851.195f, 117933.266f, 118014.44f, 118094.72f, 118174.14f, 118252.71f, 118330.46f, + 118407.4f, 118483.55f, 118558.914f, 118633.53f, 118707.4f, 118780.54f, 118852.97f, + 118924.695f, 118995.74f, 119066.11f, 119135.82f, 119204.88f, 119273.31f, 119341.125f, + 119408.32f, 119474.92f, 119540.93f, 119606.36f, 119671.22f, 119735.52f, 119799.28f, + 119862.5f, 119925.195f, 119987.36f, 120049.02f, 120110.18f, 120170.84f, 120231.016f, + 120290.71f, 120349.945f, 120408.7f, 120467.016f, 120524.875f, 120582.3f, 120639.28f, + 120695.84f, 120751.984f +}; + +// gVolRampingRhs136[k] = 1 / max(1, (256*k)^(1/17)) +f32 gVolRampingRhs136[128] = { + 1.0f, 0.72167f, 0.692837f, 0.676508f, 0.665156f, 0.656482f, 0.649479f, 0.643616f, 0.638581f, + 0.634172f, 0.630254f, 0.62673f, 0.62353f, 0.620601f, 0.617902f, 0.615399f, 0.613067f, 0.610885f, + 0.608835f, 0.606901f, 0.605073f, 0.603339f, 0.60169f, 0.600119f, 0.598618f, 0.597183f, 0.595806f, + 0.594485f, 0.593215f, 0.591991f, 0.590812f, 0.589674f, 0.588573f, 0.587509f, 0.586478f, 0.585479f, + 0.58451f, 0.583568f, 0.582654f, 0.581764f, 0.580898f, 0.580055f, 0.579233f, 0.578432f, 0.57765f, + 0.576887f, 0.576142f, 0.575414f, 0.574701f, 0.574005f, 0.573323f, 0.572656f, 0.572002f, 0.571361f, + 0.570733f, 0.570118f, 0.569514f, 0.568921f, 0.568339f, 0.567768f, 0.567207f, 0.566656f, 0.566114f, + 0.565582f, 0.565058f, 0.564543f, 0.564036f, 0.563537f, 0.563046f, 0.562563f, 0.562087f, 0.561618f, + 0.561156f, 0.560701f, 0.560253f, 0.559811f, 0.559375f, 0.558945f, 0.558521f, 0.558102f, 0.557689f, + 0.557282f, 0.55688f, 0.556483f, 0.556091f, 0.555704f, 0.555322f, 0.554944f, 0.554571f, 0.554203f, + 0.553839f, 0.553479f, 0.553123f, 0.552772f, 0.552424f, 0.55208f, 0.55174f, 0.551404f, 0.551071f, + 0.550742f, 0.550417f, 0.550095f, 0.549776f, 0.549461f, 0.549148f, 0.548839f, 0.548534f, 0.548231f, + 0.547931f, 0.547634f, 0.54734f, 0.547048f, 0.54676f, 0.546474f, 0.546191f, 0.54591f, 0.545632f, + 0.545357f, 0.545084f, 0.544813f, 0.544545f, 0.54428f, 0.544016f, 0.543755f, 0.543496f, 0.543239f, + 0.542985f, 0.542732f +}; + +// gVolRampingLhs144[k] = 2^16 * max(1, (256*k)^(1/18)) +f32 gVolRampingLhs144[128] = { + 65536.0f, 89180.734f, 92681.9f, 94793.33f, 96320.52f, 97522.02f, 98514.84f, + 99362.14f, 100101.99f, 100759.16f, 101350.664f, 101888.74f, 102382.46f, 102838.75f, + 103263.016f, 103659.58f, 104031.914f, 104382.89f, 104714.88f, 105029.89f, 105329.61f, + 105615.5f, 105888.81f, 106150.63f, 106401.914f, 106643.49f, 106876.12f, 107100.44f, + 107317.05f, 107526.47f, 107729.17f, 107925.6f, 108116.125f, 108301.12f, 108480.88f, + 108655.72f, 108825.91f, 108991.68f, 109153.28f, 109310.914f, 109464.77f, 109615.04f, + 109761.88f, 109905.46f, 110045.92f, 110183.41f, 110318.02f, 110449.91f, 110579.17f, + 110705.914f, 110830.234f, 110952.234f, 111071.99f, 111189.59f, 111305.12f, 111418.64f, + 111530.23f, 111639.95f, 111747.875f, 111854.05f, 111958.54f, 112061.4f, 112162.67f, + 112262.42f, 112360.68f, 112457.51f, 112552.93f, 112647.0f, 112739.76f, 112831.23f, + 112921.46f, 113010.484f, 113098.33f, 113185.02f, 113270.61f, 113355.11f, 113438.555f, + 113520.97f, 113602.375f, 113682.805f, 113762.27f, 113840.81f, 113918.44f, 113995.18f, + 114071.055f, 114146.08f, 114220.266f, 114293.65f, 114366.24f, 114438.06f, 114509.12f, + 114579.44f, 114649.02f, 114717.91f, 114786.086f, 114853.586f, 114920.42f, 114986.6f, + 115052.14f, 115117.055f, 115181.34f, 115245.04f, 115308.13f, 115370.65f, 115432.59f, + 115493.98f, 115554.81f, 115615.11f, 115674.875f, 115734.12f, 115792.85f, 115851.08f, + 115908.82f, 115966.07f, 116022.85f, 116079.16f, 116135.01f, 116190.4f, 116245.35f, + 116299.87f, 116353.945f, 116407.6f, 116460.84f, 116513.67f, 116566.09f, 116618.125f, + 116669.76f, 116721.01f +}; + +// gVolRampingRhs144[k] = 1 / max(1, (256*k)^(1/18)) +f32 gVolRampingRhs144[128] = { + 1.0f, 0.734867f, 0.707107f, 0.691357f, 0.680395f, 0.672012f, 0.66524f, 0.659567f, 0.654692f, + 0.650422f, 0.646626f, 0.643211f, 0.64011f, 0.637269f, 0.634651f, 0.632223f, 0.629961f, 0.627842f, + 0.625852f, 0.623975f, 0.622199f, 0.620515f, 0.618913f, 0.617387f, 0.615929f, 0.614533f, 0.613196f, + 0.611912f, 0.610677f, 0.609487f, 0.60834f, 0.607233f, 0.606163f, 0.605128f, 0.604125f, 0.603153f, + 0.60221f, 0.601294f, 0.600403f, 0.599538f, 0.598695f, 0.597874f, 0.597074f, 0.596294f, 0.595533f, + 0.59479f, 0.594064f, 0.593355f, 0.592661f, 0.591983f, 0.591319f, 0.590669f, 0.590032f, 0.589408f, + 0.588796f, 0.588196f, 0.587608f, 0.58703f, 0.586463f, 0.585906f, 0.58536f, 0.584822f, 0.584294f, + 0.583775f, 0.583265f, 0.582762f, 0.582268f, 0.581782f, 0.581303f, 0.580832f, 0.580368f, 0.579911f, + 0.57946f, 0.579017f, 0.578579f, 0.578148f, 0.577722f, 0.577303f, 0.576889f, 0.576481f, 0.576078f, + 0.575681f, 0.575289f, 0.574902f, 0.574519f, 0.574142f, 0.573769f, 0.5734f, 0.573036f, 0.572677f, + 0.572321f, 0.57197f, 0.571623f, 0.57128f, 0.57094f, 0.570605f, 0.570273f, 0.569945f, 0.56962f, + 0.569299f, 0.568981f, 0.568667f, 0.568355f, 0.568047f, 0.567743f, 0.567441f, 0.567142f, 0.566846f, + 0.566553f, 0.566263f, 0.565976f, 0.565692f, 0.56541f, 0.565131f, 0.564854f, 0.56458f, 0.564309f, + 0.56404f, 0.563773f, 0.563509f, 0.563247f, 0.562987f, 0.56273f, 0.562475f, 0.562222f, 0.561971f, + 0.561722f, 0.561476f +}; + +// gVolRampingLhs128[k] = 2^16 * max(1, (256*k)^(1/16)) +f32 gVolRampingLhs128[128] = { + 65536.0f, 92681.9f, 96785.28f, 99269.31f, 101070.33f, 102489.78f, 103664.336f, + 104667.914f, 105545.09f, 106324.92f, 107027.39f, 107666.84f, 108253.95f, 108796.87f, + 109301.95f, 109774.29f, 110217.98f, 110636.39f, 111032.33f, 111408.164f, 111765.9f, + 112107.234f, 112433.66f, 112746.46f, 113046.766f, 113335.555f, 113613.72f, 113882.02f, + 114141.164f, 114391.77f, 114634.414f, 114869.58f, 115097.74f, 115319.31f, 115534.68f, + 115744.19f, 115948.16f, 116146.875f, 116340.625f, 116529.66f, 116714.195f, 116894.46f, + 117070.64f, 117242.945f, 117411.52f, 117576.55f, 117738.17f, 117896.54f, 118051.77f, + 118204.0f, 118353.35f, 118499.92f, 118643.83f, 118785.16f, 118924.01f, 119060.47f, + 119194.625f, 119326.555f, 119456.336f, 119584.03f, 119709.71f, 119833.445f, 119955.29f, + 120075.31f, 120193.555f, 120310.08f, 120424.94f, 120538.17f, 120649.836f, 120759.97f, + 120868.62f, 120975.82f, 121081.62f, 121186.05f, 121289.14f, 121390.94f, 121491.47f, + 121590.766f, 121688.87f, 121785.79f, 121881.57f, 121976.24f, 122069.82f, 122162.33f, + 122253.805f, 122344.266f, 122433.73f, 122522.23f, 122609.77f, 122696.4f, 122782.11f, + 122866.93f, 122950.89f, 123033.99f, 123116.26f, 123197.72f, 123278.37f, 123358.24f, + 123437.34f, 123515.69f, 123593.3f, 123670.19f, 123746.36f, 123821.84f, 123896.63f, + 123970.76f, 124044.23f, 124117.04f, 124189.23f, 124260.78f, 124331.73f, 124402.07f, + 124471.83f, 124540.99f, 124609.59f, 124677.63f, 124745.12f, 124812.055f, 124878.47f, + 124944.34f, 125009.71f, 125074.57f, 125138.92f, 125202.79f, 125266.164f, 125329.06f, + 125391.5f, 125453.47f +}; + +// gVolRampingRhs128[k] = 1 / max(1, (256*k)^(1/16)) +f32 gVolRampingRhs128[128] = { + 1.0f, 0.707107f, 0.677128f, 0.660184f, 0.64842f, 0.639439f, 0.632194f, 0.626133f, 0.620929f, + 0.616375f, 0.612329f, 0.608693f, 0.605391f, 0.60237f, 0.599587f, 0.597007f, 0.594604f, 0.592355f, + 0.590243f, 0.588251f, 0.586369f, 0.584583f, 0.582886f, 0.581269f, 0.579725f, 0.578247f, 0.576832f, + 0.575473f, 0.574166f, 0.572908f, 0.571696f, 0.570525f, 0.569394f, 0.5683f, 0.567241f, 0.566214f, + 0.565218f, 0.564251f, 0.563311f, 0.562398f, 0.561508f, 0.560642f, 0.559799f, 0.558976f, 0.558173f, + 0.55739f, 0.556625f, 0.555877f, 0.555146f, 0.554431f, 0.553732f, 0.553047f, 0.552376f, 0.551719f, + 0.551075f, 0.550443f, 0.549823f, 0.549216f, 0.548619f, 0.548033f, 0.547458f, 0.546892f, 0.546337f, + 0.545791f, 0.545254f, 0.544726f, 0.544206f, 0.543695f, 0.543192f, 0.542696f, 0.542209f, 0.541728f, + 0.541255f, 0.540788f, 0.540329f, 0.539876f, 0.539429f, 0.538988f, 0.538554f, 0.538125f, 0.537702f, + 0.537285f, 0.536873f, 0.536467f, 0.536065f, 0.535669f, 0.535277f, 0.534891f, 0.534509f, 0.534131f, + 0.533759f, 0.53339f, 0.533026f, 0.532666f, 0.53231f, 0.531958f, 0.53161f, 0.531266f, 0.530925f, + 0.530588f, 0.530255f, 0.529926f, 0.529599f, 0.529277f, 0.528957f, 0.528641f, 0.528328f, 0.528018f, + 0.527711f, 0.527407f, 0.527106f, 0.526808f, 0.526513f, 0.52622f, 0.525931f, 0.525644f, 0.525359f, + 0.525077f, 0.524798f, 0.524522f, 0.524247f, 0.523975f, 0.523706f, 0.523439f, 0.523174f, 0.522911f, + 0.522651f, 0.522393f +}; + +s16 gTatumsPerBeat = TATUMS_PER_BEAT; +s8 gUnusedCount80333EE8 = UNUSED_COUNT_80333EE8; +s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_HEAP_SIZE); +s32 gAudioInitPoolSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_INIT_POOL_SIZE); +volatile s32 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; + +s8 sUnused8033EF8 = 24; + +// .bss + +volatile s32 gAudioFrameCount; + +volatile s32 gCurrAudioFrameDmaCount; + +s32 gAudioTaskIndex; +s32 gCurrAiBufferIndex; + +u64 *gAudioCmdBuffers[2]; +u64 *gAudioCmd; + +struct SPTask *gAudioTask; +struct SPTask gAudioTasks[2]; + +s16 *gAiBuffers[NUMAIBUFFERS]; +s16 gAiBufferLengths[NUMAIBUFFERS]; + +u32 gUnused80226E58[0x10]; +u16 gUnused80226E98[0x10]; + +u32 gAudioRandom; + +u64 gAudioGlobalsEndMarker; diff --git a/src/audio/us_jp/data.h b/src/audio/us_jp/data.h new file mode 100644 index 00000000..18fc856c --- /dev/null +++ b/src/audio/us_jp/data.h @@ -0,0 +1,77 @@ +#ifndef AUDIO_DATA_H +#define AUDIO_DATA_H + +#include + +#include "internal.h" +#include "types.h" + +#define AUDIO_LOCK_UNINITIALIZED 0 +#define AUDIO_LOCK_NOT_LOADING 0x76557364 +#define AUDIO_LOCK_LOADING 0x19710515 + +#define NUMAIBUFFERS 3 + +// constant .data +extern struct AudioSessionSettings gAudioSessionPresets[18]; +extern u16 D_80332388[128]; // unused + +extern f32 gPitchBendFrequencyScale[255]; +extern f32 gNoteFrequencies[128]; + +extern u8 gDefaultShortNoteVelocityTable[16]; +extern u8 gDefaultShortNoteDurationTable[16]; +extern s8 gVibratoCurve[16]; +extern struct AdsrEnvelope gDefaultEnvelope[3]; + +extern s16 *gWaveSamples[4]; + +extern u16 gHeadsetPanQuantization[10]; +extern f32 gHeadsetPanVolume[128]; +extern f32 gStereoPanVolume[128]; +extern f32 gDefaultPanVolume[128]; + +extern f32 gVolRampingLhs136[128]; +extern f32 gVolRampingRhs136[128]; +extern f32 gVolRampingLhs144[128]; +extern f32 gVolRampingRhs144[128]; +extern f32 gVolRampingLhs128[128]; +extern f32 gVolRampingRhs128[128]; + +// non-constant .data +extern s16 gTatumsPerBeat; +extern s8 gUnusedCount80333EE8; +extern s32 gAudioHeapSize; // AUDIO_HEAP_SIZE +extern s32 gAudioInitPoolSize; // AUDIO_INIT_POOL_SIZE +extern volatile s32 gAudioLoadLock; + +// .bss +extern volatile s32 gAudioFrameCount; + +// number of DMAs performed during this frame +extern volatile s32 gCurrAudioFrameDmaCount; + +extern s32 gAudioTaskIndex; +extern s32 gCurrAiBufferIndex; + +extern u64 *gAudioCmdBuffers[2]; +extern u64 *gAudioCmd; + +extern struct SPTask *gAudioTask; +extern struct SPTask gAudioTasks[2]; + +extern s16 *gAiBuffers[NUMAIBUFFERS]; +extern s16 gAiBufferLengths[NUMAIBUFFERS]; +#define AIBUFFER_LEN (0xa0 * 16) + +extern u32 gUnused80226E58[0x10]; +extern u16 gUnused80226E98[0x10]; + +extern u32 gAudioRandom; +extern s32 gAudioErrorFlags; + +#define UNUSED_COUNT_80333EE8 16 +#define AUDIO_HEAP_SIZE 0x31150 +#define AUDIO_INIT_POOL_SIZE 0x2500 + +#endif // AUDIO_DATA_H diff --git a/src/audio/us_jp/effects.c b/src/audio/us_jp/effects.c new file mode 100644 index 00000000..2ff50a2e --- /dev/null +++ b/src/audio/us_jp/effects.c @@ -0,0 +1,329 @@ +#include + +#include "effects.h" +#include "load.h" +#include "data.h" +#include "seqplayer.h" + +#ifdef VERSION_JP +#define JP_DOUBLE2(x) x##.0 +#else +#define JP_DOUBLE2(x) x +#endif + +static void sequence_channel_process_sound(struct SequenceChannel *seqChannel) { + f32 channelVolume; + f32 panLayerWeight; + f32 panFromChannel; + s32 i; + + channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->fadeVolume; + if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) { + channelVolume *= seqChannel->seqPlayer->muteVolumeScale; + } + + panFromChannel = seqChannel->pan * seqChannel->panChannelWeight; + panLayerWeight = JP_DOUBLE(1.0) - seqChannel->panChannelWeight; + + for (i = 0; i < 4; i++) { + struct SequenceChannelLayer *layer = seqChannel->layers[i]; + if (layer != NULL && layer->enabled && layer->note != NULL) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + layer->noteVelocity = layer->velocitySquare * channelVolume; + layer->notePan = (layer->pan * panLayerWeight) + panFromChannel; + } + } +} + +void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { + s32 i; + + if (seqPlayer->fadeRemainingFrames != 0) { + seqPlayer->fadeVolume += seqPlayer->fadeVelocity; + + if (seqPlayer->fadeVolume > JP_DOUBLE2(1)) { + seqPlayer->fadeVolume = JP_DOUBLE2(1); + } + if (seqPlayer->fadeVolume < 0) { + seqPlayer->fadeVolume = 0; + } + + if (--seqPlayer->fadeRemainingFrames == 0) { + switch (seqPlayer->state) { + case SEQUENCE_PLAYER_STATE_FADE_OUT: + sequence_player_disable(seqPlayer); + return; + + case SEQUENCE_PLAYER_STATE_2: + case SEQUENCE_PLAYER_STATE_3: + seqPlayer->state = SEQUENCE_PLAYER_STATE_0; + break; + + case SEQUENCE_PLAYER_STATE_4: + break; + } + } + } + + // Process channels + for (i = 0; i < CHANNELS_MAX; i++) { + if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE + && seqPlayer->channels[i]->enabled == TRUE) { + sequence_channel_process_sound(seqPlayer->channels[i]); + } + } +} + +f32 get_portamento_freq_scale(struct Portamento *p) { + u32 v0; + f32 result; + if (p->mode == 0) { + return 1.0f; + } + + p->cur += p->speed; + v0 = (u32) p->cur; + + if (v0 >= 127) + { + v0 = 127; + } + + result = JP_DOUBLE(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 127] - JP_DOUBLE(1.0)); + return result; +} + +s8 get_vibrato_pitch_change(struct VibratoState *vib) { + s32 index; + vib->time += vib->rate; + + index = (vib->time >> 10) & 0x3F; + + switch (index & 0x30) { + case 0x10: + index = 31 - index; + + case 0x00: + return vib->curve[index]; + + case 0x20: + index -= 0x20; + break; + + case 0x30: + index = 63 - index; + break; + } + + return -vib->curve[index]; +} + +f32 get_vibrato_freq_scale(struct VibratoState *vib) { + s32 pitchChange; + f32 extent; + f32 result; + + if (vib->delay != 0) { + vib->delay--; + return 1; + } + + if (vib->extentChangeTimer) { + if (vib->extentChangeTimer == 1) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; + } else { + vib->extent += + ((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer; + } + + vib->extentChangeTimer--; + } else if (vib->seqChannel->vibratoExtentTarget != (s32) vib->extent) { + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; + } + } + + if (vib->rateChangeTimer) { + if (vib->rateChangeTimer == 1) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; + } else { + vib->rate += ((s32) vib->seqChannel->vibratoRateTarget - vib->rate) / (s32) vib->rateChangeTimer; + } + + vib->rateChangeTimer--; + } else if (vib->seqChannel->vibratoRateTarget != (s32) vib->rate) { + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; + } + } + + if (vib->extent == 0) { + return 1.0f; + } + + pitchChange = get_vibrato_pitch_change(vib); + extent = (f32) vib->extent / JP_DOUBLE(4096.0); + + result = JP_DOUBLE(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 127] - JP_DOUBLE(1.0)); + return result; +} + +void note_vibrato_update(struct Note *note) { + if (note->vibratoState.active) { + note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); + if (note->parentLayer != NO_LAYER) { + note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); + } + } +} + +void note_vibrato_init(struct Note *note) { + struct VibratoState *vib; + UNUSED struct SequenceChannel *seqChannel; + + note->vibratoFreqScale = 1.0f; + note->portamentoFreqScale = 1.0f; + + vib = ¬e->vibratoState; + + if (note->parentLayer->seqChannel->vibratoExtentStart == 0 + && note->parentLayer->seqChannel->vibratoExtentTarget == 0 + && note->parentLayer->portamento.mode == 0) { + vib->active = FALSE; + return; + } + + vib->active = TRUE; + vib->time = 0; + + vib->curve = gVibratoCurve; + vib->seqChannel = note->parentLayer->seqChannel; + seqChannel = vib->seqChannel; + + if ((vib->extentChangeTimer = seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = seqChannel->vibratoExtentTarget; + } else { + vib->extent = seqChannel->vibratoExtentStart; + } + + if ((vib->rateChangeTimer = seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = seqChannel->vibratoRateTarget; + } else { + vib->rate = seqChannel->vibratoRateStart; + } + vib->delay = seqChannel->vibratoDelay; + + note->portamento = note->parentLayer->portamento; +} + +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, UNUSED s16 *volOut) { + adsr->action = 0; + adsr->state = ADSR_STATE_DISABLED; + adsr->initial = 0; + adsr->delay = 0; + adsr->velocity = 0; + adsr->envelope = envelope; + adsr->volOut = volOut; +} + +s32 adsr_update(struct AdsrState *adsr) { + u8 action = adsr->action; + switch (adsr->state) { + case ADSR_STATE_DISABLED: + return 0; + + case ADSR_STATE_INITIAL: { + adsr->current = adsr->initial; + adsr->target = adsr->initial; + if (action & ADSR_ACTION_HANG) { + adsr->state = ADSR_STATE_HANG; + break; + } + // fallthrough + } + + case ADSR_STATE_START_LOOP: + adsr->envIndex = 0; + adsr->currentHiRes = adsr->current << 0x10; + adsr->state = ADSR_STATE_LOOP; + // fallthrough + + case ADSR_STATE_LOOP: + adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay); + switch (adsr->delay) { + case ADSR_DISABLE: + adsr->state = ADSR_STATE_DISABLED; + break; + case ADSR_HANG: + adsr->state = ADSR_STATE_HANG; + break; + case ADSR_GOTO: + adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg); + break; + case ADSR_RESTART: + adsr->state = ADSR_STATE_INITIAL; + break; + + default: + adsr->target = BSWAP16(adsr->envelope[adsr->envIndex].arg); + adsr->velocity = ((adsr->target - adsr->current) << 0x10) / adsr->delay; + adsr->state = ADSR_STATE_FADE; + adsr->envIndex++; + break; + } + if (adsr->state != ADSR_STATE_FADE) { + break; + } + // fallthrough + + case ADSR_STATE_FADE: + adsr->currentHiRes += adsr->velocity; + adsr->current = adsr->currentHiRes >> 0x10; + if (--adsr->delay <= 0) { + adsr->state = ADSR_STATE_LOOP; + } + // fallthrough + + case ADSR_STATE_HANG: + break; + + case ADSR_STATE_DECAY: + case ADSR_STATE_RELEASE: { + adsr->current -= adsr->fadeOutVel; + if (adsr->sustain != 0 && adsr->state == ADSR_STATE_DECAY) { + if (adsr->current < adsr->sustain) { + adsr->current = adsr->sustain; + adsr->delay = adsr->sustain / 16; + adsr->state = ADSR_STATE_SUSTAIN; + } + break; + } + + if (adsr->current < 100) { + adsr->current = 0; + adsr->state = ADSR_STATE_DISABLED; + } + break; + } + + case ADSR_STATE_SUSTAIN: + adsr->delay -= 1; + if (adsr->delay == 0) { + adsr->state = ADSR_STATE_RELEASE; + } + break; + } + + if ((action & ADSR_ACTION_DECAY)) { + adsr->state = ADSR_STATE_DECAY; + adsr->action = action & ~ADSR_ACTION_DECAY; + } + + if ((action & ADSR_ACTION_RELEASE)) { + adsr->state = ADSR_STATE_RELEASE; + adsr->action = action & ~(ADSR_ACTION_RELEASE | ADSR_ACTION_DECAY); + } + + *adsr->volOut = adsr->current; + return 0; +} diff --git a/src/audio/us_jp/effects.h b/src/audio/us_jp/effects.h new file mode 100644 index 00000000..70cce05b --- /dev/null +++ b/src/audio/us_jp/effects.h @@ -0,0 +1,42 @@ +#ifndef AUDIO_EFFECTS_H +#define AUDIO_EFFECTS_H + +#include + +#include "internal.h" +#include "platform_info.h" + +#define ADSR_STATE_DISABLED 0 +#define ADSR_STATE_INITIAL 1 +#define ADSR_STATE_START_LOOP 2 +#define ADSR_STATE_LOOP 3 +#define ADSR_STATE_FADE 4 +#define ADSR_STATE_HANG 5 +#define ADSR_STATE_DECAY 6 +#define ADSR_STATE_RELEASE 7 +#define ADSR_STATE_SUSTAIN 8 + +#define ADSR_ACTION_RELEASE 0x10 +#define ADSR_ACTION_DECAY 0x20 +#define ADSR_ACTION_HANG 0x40 + +#define ADSR_DISABLE 0 +#define ADSR_HANG -1 +#define ADSR_GOTO -2 +#define ADSR_RESTART -3 + +// Envelopes are always stored as big endian, to match sequence files which are +// byte blobs and can embed envelopes. Hence this byteswapping macro. +#if IS_BIG_ENDIAN +#define BSWAP16(x) (x) +#else +#define BSWAP16(x) (((x) & 0xff) << 8 | (((x) >> 8) & 0xff)) +#endif + +void sequence_player_process_sound(struct SequencePlayer *seqPlayer); +void note_vibrato_update(struct Note *note); +void note_vibrato_init(struct Note *note); +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut); +s32 adsr_update(struct AdsrState *adsr); + +#endif // AUDIO_EFFECTS_H diff --git a/src/audio/us_jp/globals_start.c b/src/audio/us_jp/globals_start.c new file mode 100644 index 00000000..01498f2a --- /dev/null +++ b/src/audio/us_jp/globals_start.c @@ -0,0 +1,3 @@ +#include + +u64 gAudioGlobalsStartMarker; diff --git a/src/audio/us_jp/heap.c b/src/audio/us_jp/heap.c new file mode 100644 index 00000000..588a542f --- /dev/null +++ b/src/audio/us_jp/heap.c @@ -0,0 +1,576 @@ +#include + +#include "heap.h" +#include "data.h" +#include "load.h" +#include "synthesis.h" +#include "seqplayer.h" +#include "effects.h" + +#define ALIGN16(val) (((val) + 0xF) & ~0xF) + +struct PoolSplit { + u32 wantSeq; + u32 wantBank; + u32 wantUnused; + u32 wantCustom; +}; // size = 0x10 + +struct PoolSplit2 { + u32 wantPersistent; + u32 wantTemporary; +}; // size = 0x8 + +s16 gVolume; +s8 gReverbDownsampleRate; +u8 sReverbDownsampleRateLog; // never read + +struct SoundAllocPool gAudioSessionPool; +struct SoundAllocPool gAudioInitPool; +struct SoundAllocPool gNotesAndBuffersPool; +u8 sAudioHeapPad[0x20]; // probably two unused pools +struct SoundAllocPool gSeqAndBankPool; +struct SoundAllocPool gPersistentCommonPool; +struct SoundAllocPool gTemporaryCommonPool; + +struct SoundMultiPool gSeqLoadedPool; +struct SoundMultiPool gBankLoadedPool; +struct SoundMultiPool gUnusedLoadedPool; + +struct PoolSplit sSessionPoolSplit; +struct PoolSplit2 sSeqAndBankPoolSplit; +struct PoolSplit sPersistentCommonPoolSplit; +struct PoolSplit sTemporaryCommonPoolSplit; + +u8 gBankLoadStatus[0x40]; +u8 gSeqLoadStatus[0x100]; + +u8 gAudioUnusedBuffer[0x1000]; + +extern s32 gMaxAudioCmds; + +void reset_bank_and_seq_load_status(void) { + s32 i; + + for (i = 0; i < 64; i++) { + gBankLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; + } + + for (i = 0; i < 256; i++) { + gSeqLoadStatus[i] = SOUND_LOAD_STATUS_NOT_LOADED; + } +} + +void discard_bank(s32 bankId) { + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + struct Note *note = &gNotes[i]; + + if (note->bankId == bankId) + { + // (These prints are unclear. Arguments are picked semi-randomly.) + eu_stubbed_printf_1("Warning:Kill Note %x \n", i); + if (note->priority >= NOTE_PRIORITY_MIN) + { + eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId, + bankId, note->priority); + eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n"); + note->parentLayer->enabled = FALSE; + note->parentLayer->finished = TRUE; + } + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(&gNoteFreeLists.disabled, ¬e->listItem); + } + } +} + +void discard_sequence(s32 seqId) { + s32 i; + + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + if (gSequencePlayers[i].enabled && gSequencePlayers[i].seqId == seqId) { + sequence_player_disable(gSequencePlayers + i); + } + } +} + +void *soundAlloc(struct SoundAllocPool *pool, u32 size) { + u8 *start; + s32 last; + s32 i; + + if ((pool->cur + ALIGN16(size) <= pool->size + pool->start)) { + start = pool->cur; + pool->cur += ALIGN16(size); + last = pool->cur - start - 1; + for (i = 0; i <= last; i++) { + start[i] = 0; + } + } else { + return NULL; + } + return start; +} + +void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size) { + pool->cur = pool->start = (u8 *) ALIGN16((uintptr_t) memAddr); + pool->size = size; + pool->numAllocatedEntries = 0; +} + +void persistent_pool_clear(struct PersistentPool *persistent) { + persistent->pool.numAllocatedEntries = 0; + persistent->pool.cur = persistent->pool.start; + persistent->numEntries = 0; +} + +void temporary_pool_clear(struct TemporaryPool *temporary) { + temporary->pool.numAllocatedEntries = 0; + temporary->pool.cur = temporary->pool.start; + temporary->nextSide = 0; + temporary->entries[0].ptr = temporary->pool.start; + temporary->entries[1].ptr = temporary->pool.size + temporary->pool.start; + temporary->entries[0].id = -1; + temporary->entries[1].id = -1; +} + +void unused_803160F8(struct SoundAllocPool *pool) { + pool->numAllocatedEntries = 0; + pool->cur = pool->start; +} + +void sound_init_main_pools(s32 sizeForAudioInitPool) { + sound_alloc_pool_init(&gAudioInitPool, gAudioHeap, sizeForAudioInitPool); + sound_alloc_pool_init(&gAudioSessionPool, gAudioHeap + sizeForAudioInitPool, gAudioHeapSize - sizeForAudioInitPool); +} + +void session_pools_init(struct PoolSplit *a) { + gAudioSessionPool.cur = gAudioSessionPool.start; + sound_alloc_pool_init(&gNotesAndBuffersPool, soundAlloc(&gAudioSessionPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gSeqAndBankPool, soundAlloc(&gAudioSessionPool, a->wantCustom), a->wantCustom); +} + +void seq_and_bank_pool_init(struct PoolSplit2 *a) { + gSeqAndBankPool.cur = gSeqAndBankPool.start; + sound_alloc_pool_init(&gPersistentCommonPool, soundAlloc(&gSeqAndBankPool, a->wantPersistent), a->wantPersistent); + sound_alloc_pool_init(&gTemporaryCommonPool, soundAlloc(&gSeqAndBankPool, a->wantTemporary), a->wantTemporary); +} + +void persistent_pools_init(struct PoolSplit *a) { + gPersistentCommonPool.cur = gPersistentCommonPool.start; + sound_alloc_pool_init(&gSeqLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.persistent.pool, soundAlloc(&gPersistentCommonPool, a->wantUnused), + a->wantUnused); + persistent_pool_clear(&gSeqLoadedPool.persistent); + persistent_pool_clear(&gBankLoadedPool.persistent); + persistent_pool_clear(&gUnusedLoadedPool.persistent); +} + +void temporary_pools_init(struct PoolSplit *a) { + gTemporaryCommonPool.cur = gTemporaryCommonPool.start; + sound_alloc_pool_init(&gSeqLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantSeq), a->wantSeq); + sound_alloc_pool_init(&gBankLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantBank), a->wantBank); + sound_alloc_pool_init(&gUnusedLoadedPool.temporary.pool, soundAlloc(&gTemporaryCommonPool, a->wantUnused), + a->wantUnused); + temporary_pool_clear(&gSeqLoadedPool.temporary); + temporary_pool_clear(&gBankLoadedPool.temporary); + temporary_pool_clear(&gUnusedLoadedPool.temporary); +} + +UNUSED static void unused_803163D4(void) { +} + +void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) { + // arg3 = 0, 1 or 2? + + struct TemporaryPool *tp; + struct SoundAllocPool *pool; + void *ret; + u16 UNUSED _firstVal; + u16 UNUSED _secondVal; + u32 nullID = -1; + UNUSED s32 i; + u8 *table; + u8 isSound; + u16 firstVal; + u16 secondVal; + u32 bothDiscardable; + u32 leftDiscardable, rightDiscardable; + u32 leftNotLoaded, rightNotLoaded; + u32 leftAvail, rightAvail; + + if (arg3 == 0) { + tp = &arg0->temporary; + if (arg0 == &gSeqLoadedPool) { + table = gSeqLoadStatus; + isSound = FALSE; + } else if (arg0 == &gBankLoadedPool) { + table = gBankLoadStatus; + isSound = TRUE; + } + + firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]); + secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]); + + leftNotLoaded = (firstVal == SOUND_LOAD_STATUS_NOT_LOADED); + leftDiscardable = (firstVal == SOUND_LOAD_STATUS_DISCARDABLE); + leftAvail = (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS); + rightNotLoaded = (secondVal == SOUND_LOAD_STATUS_NOT_LOADED); + rightDiscardable = (secondVal == SOUND_LOAD_STATUS_DISCARDABLE); + rightAvail = (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS); + bothDiscardable = (leftDiscardable && rightDiscardable); + + if (leftNotLoaded) { + tp->nextSide = 0; + } else if (rightNotLoaded) { + tp->nextSide = 1; + } else if (bothDiscardable) { + // Use the opposite side from last time. + } else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { // ??! (I blame copt) + tp->nextSide = 0; + } else if (rightDiscardable) { + tp->nextSide = 1; + } else if (leftAvail) { + tp->nextSide = 0; + } else if (rightAvail) { + tp->nextSide = 1; + } else { + // Both left and right sides are being loaded into. + return NULL; + } + + pool = &arg0->temporary.pool; + if (tp->entries[tp->nextSide].id != (s8)nullID) { + table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED; + if (isSound == TRUE) { + discard_bank(tp->entries[tp->nextSide].id); + } + } + + switch (tp->nextSide) { + case 0: + tp->entries[0].ptr = pool->start; + tp->entries[0].id = id; + tp->entries[0].size = size; + + pool->cur = pool->start + size; + + if (tp->entries[1].ptr < pool->cur) { + eu_stubbed_printf_0("WARNING: Before Area Overlaid After."); + + // Throw out the entry on the other side if it doesn't fit. + // (possible @bug: what if it's currently being loaded?) + table[tp->entries[1].id] = SOUND_LOAD_STATUS_NOT_LOADED; + + switch (isSound) { + case FALSE: + discard_sequence(tp->entries[1].id); + break; + case TRUE: + discard_bank(tp->entries[1].id); + break; + } + + tp->entries[1].id = (s32)nullID; + tp->entries[1].ptr = pool->size + pool->start; + } + + ret = tp->entries[0].ptr; + break; + + case 1: + tp->entries[1].ptr = pool->size + pool->start - size - 0x10; + tp->entries[1].id = id; + tp->entries[1].size = size; + + if (tp->entries[1].ptr < pool->cur) { + eu_stubbed_printf_0("WARNING: After Area Overlaid Before."); + + table[tp->entries[0].id] = SOUND_LOAD_STATUS_NOT_LOADED; + + switch (isSound) { + case FALSE: + discard_sequence(tp->entries[0].id); + break; + case TRUE: + discard_bank(tp->entries[0].id); + break; + } + + tp->entries[0].id = (s32)nullID; + pool->cur = pool->start; + } + + ret = tp->entries[1].ptr; + break; + + default: + eu_stubbed_printf_1("MEMORY:SzHeapAlloc ERROR: sza->side %d\n", tp->nextSide); + return NULL; + } + + // Switch sides for next time in case both entries are + // SOUND_LOAD_STATUS_DISCARDABLE. + tp->nextSide ^= 1; + + return ret; + } + + arg0->persistent.entries[arg0->persistent.numEntries].ptr = soundAlloc(&arg0->persistent.pool, arg1 * size); + + if (arg0->persistent.entries[arg0->persistent.numEntries].ptr == NULL) + { + switch (arg3) { + case 2: + // Prevent tail call optimization. + ret = alloc_bank_or_seq(arg0, arg1, size, 0, id); + return ret; + case 1: + eu_stubbed_printf_1("MEMORY:StayHeap OVERFLOW (REQ:%d)", arg1 * size); + return NULL; + } + } + + // TODO: why is this guaranteed to write <= 32 entries...? + // Because the buffer is small enough that more don't fit? + arg0->persistent.entries[arg0->persistent.numEntries].id = id; + arg0->persistent.entries[arg0->persistent.numEntries].size = size; + arg0->persistent.numEntries++; return arg0->persistent.entries[arg0->persistent.numEntries - 1].ptr; +} + +void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) { + u32 i; + UNUSED void *ret; + struct TemporaryPool *temporary = &arg0->temporary; + + if (arg1 == 0) { + // Try not to overwrite sound that we have just accessed, by setting nextSide appropriately. + if (temporary->entries[0].id == id) { + temporary->nextSide = 1; + return temporary->entries[0].ptr; + } else if (temporary->entries[1].id == id) { + temporary->nextSide = 0; + return temporary->entries[1].ptr; + } + eu_stubbed_printf_1("Auto Heap Unhit for ID %d\n", id); + return NULL; + } else { + struct PersistentPool *persistent = &arg0->persistent; + for (i = 0; i < persistent->numEntries; i++) { + if (id == persistent->entries[i].id) { + eu_stubbed_printf_2("Cache hit %d at stay %d\n", id, i); + return persistent->entries[i].ptr; + } + } + + if (arg1 == 2) { + // Prevent tail call optimization by using a temporary. + // Either copt or -Wo,-notail. + ret = get_bank_or_seq(arg0, 0, id); + return ret; + } + return NULL; + } +} + +void decrease_reverb_gain(void) { + gSynthesisReverb.reverbGain -= gSynthesisReverb.reverbGain / 4; +} + + +/** + * Waits until a specified number of audio frames have been created + */ +void wait_for_audio_frames(s32 frames) { + gAudioFrameCount = 0; + // Sound thread will update gAudioFrameCount + while (gAudioFrameCount < frames) { + // spin + } +} + +void audio_reset_session(struct AudioSessionSettings *preset) { + s16 *mem; + s8 updatesPerFrame; + s32 reverbWindowSize; + s32 k; + s32 i; + s32 j; + s32 persistentMem; + s32 temporaryMem; + s32 totalMem; + s32 wantMisc; + s32 frames; + s32 remainingDmas; + eu_stubbed_printf_1("Heap Reconstruct Start %x\n", gAudioResetPresetIdToLoad); + + if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { + decrease_reverb_gain(); + for (i = 0; i < gMaxSimultaneousNotes; i++) { + if (gNotes[i].enabled && gNotes[i].adsr.state != ADSR_STATE_DISABLED) { + gNotes[i].adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; + gNotes[i].adsr.action |= ADSR_ACTION_RELEASE; + } + } + + // Wait for all notes to stop playing + frames = 0; + for (;;) { + wait_for_audio_frames(1); + frames++; + if (frames > 4 * 60) { + // Break after 4 seconds + break; + } + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + if (gNotes[i].enabled) { + break; + } + } + + if (i == gMaxSimultaneousNotes) { + // All zero, break early + break; + } + } + + // Wait for the reverb to finish as well + decrease_reverb_gain(); + wait_for_audio_frames(3); + + // The audio interface is double buffered; thus, we have to take the + // load lock for 2 frames for the buffers to free up before we can + // repurpose memory. Make that 3 frames, just in case. + gAudioLoadLock = AUDIO_LOCK_LOADING; + wait_for_audio_frames(3); + + remainingDmas = gCurrAudioFrameDmaCount; + while (remainingDmas > 0) { + for (i = 0; i < gCurrAudioFrameDmaCount; i++) { + if (osRecvMesg(&gCurrAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK) == 0) + remainingDmas--; + } + } + gCurrAudioFrameDmaCount = 0; + + for (j = 0; j < NUMAIBUFFERS; j++) { + for (k = 0; k < (s32) (AIBUFFER_LEN / sizeof(s16)); k++) { + gAiBuffers[j][k] = 0; + } + } + } + + gSampleDmaNumListItems = 0; + reverbWindowSize = preset->reverbWindowSize; + gAiFrequency = osAiSetFrequency(preset->frequency); + gMaxSimultaneousNotes = preset->maxSimultaneousNotes; + gSamplesPerFrameTarget = ALIGN16(gAiFrequency / 60); + gReverbDownsampleRate = preset->reverbDownsampleRate; + + switch (gReverbDownsampleRate) { + case 1: + sReverbDownsampleRateLog = 0; + break; + case 2: + sReverbDownsampleRateLog = 1; + break; + case 4: + sReverbDownsampleRateLog = 2; + break; + case 8: + sReverbDownsampleRateLog = 3; + break; + case 16: + sReverbDownsampleRateLog = 4; + break; + default: + sReverbDownsampleRateLog = 0; + } + + gReverbDownsampleRate = preset->reverbDownsampleRate; + gVolume = preset->volume; + gMinAiBufferLength = gSamplesPerFrameTarget - 0x10; + updatesPerFrame = gSamplesPerFrameTarget / 160 + 1; + gAudioUpdatesPerFrame = gSamplesPerFrameTarget / 160 + 1; + + // Compute conversion ratio from the internal unit tatums/tick to the + // external beats/minute (JP) or tatums/minute (US). In practice this is + // 300 on JP and 14360 on US. +#ifdef VERSION_JP + gTempoInternalToExternal = updatesPerFrame * 3600 / gTatumsPerBeat; +#else + gTempoInternalToExternal = (u32)(updatesPerFrame * 2880000.0f / gTatumsPerBeat / 16.713f); +#endif + gMaxAudioCmds = gMaxSimultaneousNotes * 20 * updatesPerFrame + 320; + + persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentBankMem + preset->persistentSeqMem); + temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporaryBankMem + preset->temporarySeqMem); + totalMem = persistentMem + temporaryMem; + wantMisc = gAudioSessionPool.size - totalMem - 0x100; + sSessionPoolSplit.wantSeq = wantMisc; + sSessionPoolSplit.wantCustom = totalMem; + session_pools_init(&sSessionPoolSplit); + sSeqAndBankPoolSplit.wantPersistent = persistentMem; + sSeqAndBankPoolSplit.wantTemporary = temporaryMem; + seq_and_bank_pool_init(&sSeqAndBankPoolSplit); + sPersistentCommonPoolSplit.wantSeq = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem); + sPersistentCommonPoolSplit.wantBank = DOUBLE_SIZE_ON_64_BIT(preset->persistentBankMem); + sPersistentCommonPoolSplit.wantUnused = 0; + persistent_pools_init(&sPersistentCommonPoolSplit); + sTemporaryCommonPoolSplit.wantSeq = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem); + sTemporaryCommonPoolSplit.wantBank = DOUBLE_SIZE_ON_64_BIT(preset->temporaryBankMem); + sTemporaryCommonPoolSplit.wantUnused = 0; + temporary_pools_init(&sTemporaryCommonPoolSplit); + reset_bank_and_seq_load_status(); + + for (j = 0; j < 2; j++) { + gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64)); + } + + gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * sizeof(struct Note)); + note_init_all(); + init_note_free_list(); + + if (reverbWindowSize == 0) { + gSynthesisReverb.useReverb = 0; + } else { + gSynthesisReverb.useReverb = 8; + gSynthesisReverb.ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, reverbWindowSize * 2); + gSynthesisReverb.ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, reverbWindowSize * 2); + gSynthesisReverb.nextRingBufferPos = 0; + gSynthesisReverb.unkC = 0; + gSynthesisReverb.curFrame = 0; + gSynthesisReverb.bufSizePerChannel = reverbWindowSize; + gSynthesisReverb.reverbGain = preset->reverbGain; + gSynthesisReverb.framesLeftToIgnore = 2; + if (gReverbDownsampleRate != 1) { + gSynthesisReverb.resampleFlags = A_INIT; + gSynthesisReverb.resampleRate = 0x8000 / gReverbDownsampleRate; + gSynthesisReverb.resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + gSynthesisReverb.resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + gSynthesisReverb.unk24 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + gSynthesisReverb.unk28 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + for (i = 0; i < gAudioUpdatesPerFrame; i++) { + mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); + gSynthesisReverb.items[0][i].toDownsampleLeft = mem; + gSynthesisReverb.items[0][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); + mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); + gSynthesisReverb.items[1][i].toDownsampleLeft = mem; + gSynthesisReverb.items[1][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); + } + } + } + + init_sample_dma_buffers(gMaxSimultaneousNotes); + + osWritebackDCacheAll(); + + if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { + gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; + } +} + diff --git a/src/audio/us_jp/heap.h b/src/audio/us_jp/heap.h new file mode 100644 index 00000000..8a2e6f5c --- /dev/null +++ b/src/audio/us_jp/heap.h @@ -0,0 +1,94 @@ +#ifndef AUDIO_HEAP_H +#define AUDIO_HEAP_H + +#include + +#include "internal.h" + +#define SOUND_LOAD_STATUS_NOT_LOADED 0 +#define SOUND_LOAD_STATUS_IN_PROGRESS 1 +#define SOUND_LOAD_STATUS_COMPLETE 2 +#define SOUND_LOAD_STATUS_DISCARDABLE 3 +#define SOUND_LOAD_STATUS_4 4 +#define SOUND_LOAD_STATUS_5 5 + +#define IS_BANK_LOAD_COMPLETE(bankId) (gBankLoadStatus[bankId] >= SOUND_LOAD_STATUS_COMPLETE) +#define IS_SEQ_LOAD_COMPLETE(seqId) (gSeqLoadStatus[seqId] >= SOUND_LOAD_STATUS_COMPLETE) + +struct SoundAllocPool { + u8 *start; + u8 *cur; + u32 size; + s32 numAllocatedEntries; +}; // size = 0x10 + +struct SeqOrBankEntry { + u8 *ptr; + u32 size; + s32 id; // seqId or bankId +}; // size = 0xC + +struct PersistentPool { + /*0x00*/ u32 numEntries; + /*0x04*/ struct SoundAllocPool pool; + /*0x14*/ struct SeqOrBankEntry entries[32]; +}; // size = 0x194 + +struct TemporaryPool { + /*0x00*/ u32 nextSide; + /*0x04*/ struct SoundAllocPool pool; + /*0x14*/ struct SeqOrBankEntry entries[2]; +}; // size = 0x2C + +struct SoundMultiPool { + /*0x000*/ struct PersistentPool persistent; + /*0x194*/ struct TemporaryPool temporary; + /* */ u32 pad2[4]; +}; // size = 0x1D0 + +struct Unk1Pool { + struct SoundAllocPool pool; + struct SeqOrBankEntry entries[32]; +}; + +struct UnkEntry { + s8 used; + s8 medium; + s8 bankId; + u32 pad; + u8 *srcAddr; + u8 *dstAddr; + u32 size; +}; + +struct UnkPool { + /*0x00*/ struct SoundAllocPool pool; + /*0x10*/ struct UnkEntry entries[64]; + /*0x510*/ s32 numEntries; + /*0x514*/ u32 unk514; +}; + +extern u8 gAudioHeap[]; +extern s16 gVolume; +extern s8 gReverbDownsampleRate; +extern struct SoundAllocPool gAudioInitPool; +extern struct SoundAllocPool gNotesAndBuffersPool; +extern struct SoundAllocPool gPersistentCommonPool; +extern struct SoundAllocPool gTemporaryCommonPool; +extern struct SoundMultiPool gSeqLoadedPool; +extern struct SoundMultiPool gBankLoadedPool; +extern u8 gBankLoadStatus[64]; +extern u8 gSeqLoadStatus[256]; +extern volatile u8 gAudioResetStatus; +extern u8 gAudioResetPresetIdToLoad; + +void *soundAlloc(struct SoundAllocPool *pool, u32 size); +void *sound_alloc_uninitialized(struct SoundAllocPool *pool, u32 size); +void sound_init_main_pools(s32 sizeForAudioInitPool); +void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size); +void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id); +void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id); +void audio_reset_session(struct AudioSessionSettings *preset); +void discard_bank(s32 bankId); + +#endif // AUDIO_HEAP_H diff --git a/src/audio/us_jp/internal.h b/src/audio/us_jp/internal.h new file mode 100644 index 00000000..ffd02188 --- /dev/null +++ b/src/audio/us_jp/internal.h @@ -0,0 +1,456 @@ +#ifndef AUDIO_INTERNAL_H +#define AUDIO_INTERNAL_H + +#include + +#include "types.h" + +#define SEQUENCE_PLAYERS 3 +#define SEQUENCE_CHANNELS 32 +#ifdef VERSION_JP +#define SEQUENCE_LAYERS 48 +#else +#define SEQUENCE_LAYERS 52 +#endif + +#define LAYERS_MAX 4 +#define CHANNELS_MAX 16 + +#define NO_LAYER ((struct SequenceChannelLayer *)(-1)) + +#define MUTE_BEHAVIOR_STOP_SCRIPT 0x80 // stop processing sequence/channel scripts +#define MUTE_BEHAVIOR_STOP_NOTES 0x40 // prevent further notes from playing +#define MUTE_BEHAVIOR_SOFTEN 0x20 // lower volume, by default to half + +#define SEQUENCE_PLAYER_STATE_0 0 +#define SEQUENCE_PLAYER_STATE_FADE_OUT 1 +#define SEQUENCE_PLAYER_STATE_2 2 +#define SEQUENCE_PLAYER_STATE_3 3 +#define SEQUENCE_PLAYER_STATE_4 4 + +#define NOTE_PRIORITY_DISABLED 0 +#define NOTE_PRIORITY_STOPPING 1 +#define NOTE_PRIORITY_MIN 2 +#define NOTE_PRIORITY_DEFAULT 3 + +#define TATUMS_PER_BEAT 48 + +// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing +#define CODEC_ADPCM 0 +#define CODEC_S8 1 +#define CODEC_SKIP 2 + +#ifdef VERSION_JP +#define TEMPO_SCALE 1 +#else +#define TEMPO_SCALE TATUMS_PER_BEAT +#endif + +#ifdef VERSION_JP +#define JP_DOUBLE(x) x +#else +#define JP_DOUBLE(x) x ## f +#endif + +// Convert u8 or u16 to f32. On JP, this uses a u32->f32 conversion, +// resulting in more bloated codegen, while on later versions it goes through s32. +// Since u8 and u16 fit losslessly in both, behavior is the same. +#ifdef VERSION_JP +#define FLOAT_CAST(x) (f32) (x) +#else +#define FLOAT_CAST(x) (f32) (s32) (x) +#endif + +// No-op printf macro which leaves string literals in rodata in IDO. IDO +// doesn't support variadic macros, so instead we let the parameter list +// expand to a no-op comma expression. Another possibility is that it might +// have expanded to something with "if (0)". See also goddard/gd_main.h. +// On US/JP, -sopt optimizes away these except for external.c. +#ifdef __sgi +#define stubbed_printf +#else +#define stubbed_printf(...) +#endif + +#define eu_stubbed_printf_0(msg) +#define eu_stubbed_printf_1(msg, a) +#define eu_stubbed_printf_2(msg, a, b) +#define eu_stubbed_printf_3(msg, a, b, c) + +struct NotePool; + +struct AudioListItem { + // A node in a circularly linked list. Each node is either a head or an item: + // - Items can be either detached (prev = NULL), or attached to a list. + // 'value' points to something of interest. + // - List heads are always attached; if a list is empty, its head points + // to itself. 'count' contains the size of the list. + // If the list holds notes, 'pool' points back to the pool where it lives. + // Otherwise, that member is NULL. + struct AudioListItem *prev; + struct AudioListItem *next; + union { + void *value; // either Note* or SequenceChannelLayer* + s32 count; + } u; + struct NotePool *pool; +}; // size = 0x10 + +struct NotePool { + struct AudioListItem disabled; + struct AudioListItem decaying; + struct AudioListItem releasing; + struct AudioListItem active; +}; + +struct VibratoState { + /*0x00*/ struct SequenceChannel *seqChannel; + /*0x04*/ u32 time; + /*0x08*/ s8 *curve; + /*0x0C*/ u8 active; + /*0x0E*/ u16 rate; + /*0x10*/ u16 extent; + /*0x12*/ u16 rateChangeTimer; + /*0x14*/ u16 extentChangeTimer; + /*0x16*/ u16 delay; +}; // size = 0x18 + +// Pitch sliding by up to one octave in the positive direction. Negative +// direction is "supported" by setting extent to be negative. The code +// extrapolates exponentially in the wrong direction in that case, but that +// doesn't prevent seqplayer from doing it, AFAICT. +struct Portamento { + u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 + f32 cur; + f32 speed; + f32 extent; +}; // size = 0x10 + +struct AdsrEnvelope { + s16 delay; + s16 arg; +}; // size = 0x4 + +struct AdpcmLoop { + u32 start; + u32 end; + u32 count; + u32 pad; + s16 state[16]; // only exists if count != 0. 8-byte aligned +}; + +struct AdpcmBook { + s32 order; + s32 npredictors; + s16 book[1]; // size 8 * order * npredictors. 8-byte aligned +}; + +struct AudioBankSample { + u8 unused; + u8 loaded; + u8 *sampleAddr; + struct AdpcmLoop *loop; + struct AdpcmBook *book; + u32 sampleSize; // never read. either 0 or 1 mod 9, depending on padding +}; + +struct AudioBankSound { + struct AudioBankSample *sample; + f32 tuning; // frequency scale factor +}; // size = 0x8 + +struct Instrument { + /*0x00*/ u8 loaded; + /*0x01*/ u8 normalRangeLo; + /*0x02*/ u8 normalRangeHi; + /*0x03*/ u8 releaseRate; + /*0x04*/ struct AdsrEnvelope *envelope; + /*0x08*/ struct AudioBankSound lowNotesSound; + /*0x10*/ struct AudioBankSound normalNotesSound; + /*0x18*/ struct AudioBankSound highNotesSound; +}; // size = 0x20 + +struct Drum { + u8 releaseRate; + u8 pan; + u8 loaded; + struct AudioBankSound sound; + struct AdsrEnvelope *envelope; +}; + +struct AudioBank { + struct Drum **drums; + struct Instrument *instruments[1]; +}; // dynamic size + +struct CtlEntry { + u8 unused; + u8 numInstruments; + u8 numDrums; + struct Instrument **instruments; + struct Drum **drums; +}; // size = 0xC + +struct M64ScriptState { + u8 *pc; + u8 *stack[4]; + u8 remLoopIters[4]; + u8 depth; +}; // size = 0x1C + +// Also known as a Group, according to debug strings. +struct SequencePlayer { + /*0x000*/ volatile u8 enabled : 1; + /*0x000*/ u8 finished : 1; // never read + /*0x000*/ u8 muted : 1; + /*0x000*/ u8 seqDmaInProgress : 1; + /*0x000*/ u8 bankDmaInProgress : 1; + /*0x001*/ s8 seqVariation; + /*0x002*/ u8 state; + /*0x003*/ u8 noteAllocPolicy; + /*0x004*/ u8 muteBehavior; + /*0x005*/ u8 seqId; + /*0x006*/ u8 defaultBank[1]; // must be an array to get a comparison + // to match; other u8's might also be part of that array + /*0x007*/ u8 loadingBankId; + /*0x008*/ u8 loadingBankNumInstruments; + /*0x009*/ u8 loadingBankNumDrums; + /*0x00A*/ u16 tempo; // beats per minute in JP, tatums per minute in US + /*0x00C*/ u16 tempoAcc; + /*0x00E*/ u16 fadeRemainingFrames; + /*0x010*/ s16 transposition; + /*0x012*/ u16 delay; + /*0x014*/ u8 *seqData; // buffer of some sort + /*0x018*/ f32 fadeVolume; // set to 1.0f + /*0x01C*/ f32 fadeVelocity; // set to 0.0f + /*0x020*/ f32 volume; // set to 0.0f + /*0x024*/ f32 muteVolumeScale; // set to 0.5f + /* */ u8 pad2[4]; + /*0x02C*/ struct SequenceChannel *channels[CHANNELS_MAX]; + /*0x06C*/ struct M64ScriptState scriptState; + /*0x088*/ u8 *shortNoteVelocityTable; + /*0x08C*/ u8 *shortNoteDurationTable; + /*0x090*/ struct NotePool notePool; + /*0x0D0*/ OSMesgQueue seqDmaMesgQueue; + /*0x0E8*/ OSMesg seqDmaMesg; + /*0x0EC*/ OSIoMesg seqDmaIoMesg; + /*0x100*/ OSMesgQueue bankDmaMesgQueue; + /*0x118*/ OSMesg bankDmaMesg; + /*0x11C*/ OSIoMesg bankDmaIoMesg; + /*0x130*/ u8 *bankDmaCurrMemAddr; + /*0x134*/ struct AudioBank *loadingBank; + /*0x138*/ uintptr_t bankDmaCurrDevAddr; + /*0x13C*/ ssize_t bankDmaRemaining; +}; // size = 0x140 + +struct AdsrSettings { + u8 releaseRate; + u16 sustain; // sustain level, 2^16 = max + struct AdsrEnvelope *envelope; +}; // size = 0x8 + +struct AdsrState { + /*0x00*/ u8 action; + /*0x01*/ u8 state; + /*0x02*/ s16 initial; // always 0 + /*0x04*/ s16 target; + /*0x06*/ s16 current; + /*0x08*/ s16 envIndex; + /*0x0A*/ s16 delay; + /*0x0C*/ s16 sustain; + /*0x0E*/ s16 fadeOutVel; + /*0x10*/ s32 velocity; + /*0x14*/ s32 currentHiRes; + /*0x18*/ s16 *volOut; + /*0x1C*/ struct AdsrEnvelope *envelope; +}; // size = 0x20 + +struct ReverbBitsData { + /* 0x00 */ u8 bit0 : 1; + /* 0x00 */ u8 bit1 : 1; + /* 0x00 */ u8 bit2 : 1; + /* 0x00 */ u8 usesHeadsetPanEffects : 1; + /* 0x00 */ u8 stereoHeadsetEffects : 2; + /* 0x00 */ u8 strongRight : 1; + /* 0x00 */ u8 strongLeft : 1; +}; + +union ReverbBits { + /* 0x00 */ struct ReverbBitsData s; + /* 0x00 */ u8 asByte; +}; +struct ReverbInfo { + u8 reverbVol; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 + u8 pan; + union ReverbBits reverbBits; + f32 freqScale; + f32 velocity; + s32 unused; + s16 *filter; +}; + +struct NoteAttributes { + u8 reverbVol; + f32 freqScale; + f32 velocity; + f32 pan; +}; // size = 0x10 + +// Also known as a SubTrack, according to debug strings. +// Confusingly, a SubTrack is a container of Tracks. +struct SequenceChannel { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 stopScript : 1; + /*0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething + /*0x00*/ u8 hasInstrument : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00*/ u8 largeNotes : 1; // notes specify duration and velocity + /*0x00*/ u8 unused : 1; // never read, set to 0 + /*0x01*/ u8 noteAllocPolicy; + /*0x02*/ u8 muteBehavior; + /*0x03*/ u8 reverbVol; // Q1.7 + /*0x04*/ u8 notePriority; // 0-3 + /*0x05*/ u8 bankId; + /*0x06*/ u8 updatesPerFrameUnused; + /*0x08*/ u16 vibratoRateStart; // initially 0x800 + /*0x0A*/ u16 vibratoExtentStart; + /*0x0C*/ u16 vibratoRateTarget; // initially 0x800 + /*0x0E*/ u16 vibratoExtentTarget; + /*0x10*/ u16 vibratoRateChangeDelay; + /*0x12*/ u16 vibratoExtentChangeDelay; + /*0x14*/ u16 vibratoDelay; + /*0x16*/ u16 delay; + /*0x18*/ s16 instOrWave; // either 0 (none), instrument index + 1, or + // 0x80..0x83 for sawtooth/triangle/sine/square waves. + /*0x1A*/ s16 transposition; + /*0x1C*/ f32 volumeScale; + /*0x20*/ f32 volume; + /*0x24*/ f32 pan; + /*0x28*/ f32 panChannelWeight; // proportion of pan that comes from the channel (0..1) + /*0x2C*/ f32 freqScale; + /*0x30*/ u8 (*dynTable)[][2]; + /*0x34*/ struct Note *noteUnused; // never read + /*0x38*/ struct SequenceChannelLayer *layerUnused; // never read + /*0x3C*/ struct Instrument *instrument; + /*0x40*/ struct SequencePlayer *seqPlayer; + /*0x44*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; + /*0x54*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, + // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment + /*0x5C*/ struct M64ScriptState scriptState; + /*0x78*/ struct AdsrSettings adsr; + /*0x80*/ struct NotePool notePool; +}; // size = 0xC0 + +// Also known as a Track, according to debug strings. +struct SequenceChannelLayer { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 stopSomething : 1; // ? + /*0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound + /*0x01*/ u8 status; + /*0x02*/ u8 noteDuration; // set to 0x80 + /*0x03*/ u8 portamentoTargetNote; + /*0x04*/ struct Portamento portamento; + /*0x14*/ struct AdsrSettings adsr; + /*0x1C*/ u16 portamentoTime; + /*0x1E*/ s16 transposition; // #semitones added to play commands + // (m64 instruction encoding only allows referring to the limited range + // 0..0x3f; this makes 0x40..0x7f accessible as well) + /*0x20*/ f32 freqScale; + /*0x24*/ f32 velocitySquare; + /*0x28*/ f32 pan; // 0..1 + /*0x2C*/ f32 noteVelocity; + /*0x30*/ f32 notePan; + /*0x34*/ f32 noteFreqScale; + /*0x38*/ s16 shortNoteDefaultPlayPercentage; + /*0x3A*/ s16 playPercentage; // it's not really a percentage... + /*0x3C*/ s16 delay; + /*0x3E*/ s16 duration; + /*0x40*/ s16 delayUnused; // set to 'delay', never read + /*0x44*/ struct Note *note; + /*0x48*/ struct Instrument *instrument; + /*0x4C*/ struct AudioBankSound *sound; + /*0x50*/ struct SequenceChannel *seqChannel; + /*0x54*/ struct M64ScriptState scriptState; + /*0x70*/ struct AudioListItem listItem; +}; // size = 0x80 + +// volatile Note, needed in synthesis_process_notes +struct vNote { + /*0x00*/ volatile u8 enabled : 1; + long long int force_structure_alignment; +}; +struct Note { + /*0x00*/ u8 enabled : 1; + /*0x00*/ u8 needsInit : 1; + /*0x00*/ u8 restart : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 envMixerNeedsInit : 1; + /*0x00*/ u8 stereoStrongRight : 1; + /*0x00*/ u8 stereoStrongLeft : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*0x01*/ u8 usesHeadsetPanEffects; + /*0x02*/ u8 unk2; + /*0x03*/ u8 sampleDmaIndex; + /*0x04*/ u8 priority; + /*0x05*/ u8 sampleCount; // 0, 8, 16, 32 or 64 + /*0x06*/ u8 instOrWave; + /*0x07*/ u8 bankId; + /*0x08*/ s16 adsrVolScale; + /* */ u8 pad1[2]; + /*0x0C*/ u16 headsetPanRight; + /*0x0E*/ u16 headsetPanLeft; + /*0x10*/ u16 prevHeadsetPanRight; + /*0x12*/ u16 prevHeadsetPanLeft; + /*0x14*/ s32 samplePosInt; + /*0x18*/ f32 portamentoFreqScale; + /*0x1C*/ f32 vibratoFreqScale; + /*0x20*/ u16 samplePosFrac; + /*0x24*/ struct AudioBankSound *sound; + /*0x28*/ struct SequenceChannelLayer *prevParentLayer; + /*0x2C*/ struct SequenceChannelLayer *parentLayer; + /*0x30*/ struct SequenceChannelLayer *wantedParentLayer; + /*0x34*/ struct NoteSynthesisBuffers *synthesisBuffers; + /*0x38*/ f32 frequency; + /*0x3C*/ u16 targetVolLeft; // Q1.15, but will always be non-negative + /*0x3E*/ u16 targetVolRight; // Q1.15, but will always be non-negative + /*0x40*/ u8 reverbVol; // Q1.7 + /*0x41*/ u8 unused1; // never read, set to 0x3f + /*0x44*/ struct NoteAttributes attributes; + /*0x54*/ struct AdsrState adsr; + /*0x74*/ struct Portamento portamento; + /*0x84*/ struct VibratoState vibratoState; + /*0x9C*/ s16 curVolLeft; // Q1.15, but will always be non-negative + /*0x9E*/ s16 curVolRight; // Q1.15, but will always be non-negative + /*0xA0*/ s16 reverbVolShifted; // Q1.15 + /*0xA2*/ s16 unused2; // never read, set to 0 + /*0xA4*/ struct AudioListItem listItem; + /* */ u8 pad2[0xc]; +}; // size = 0xC0 + +struct NoteSynthesisBuffers { + s16 adpcmdecState[0x10]; + s16 finalResampleState[0x10]; + s16 mixEnvelopeState[0x28]; + s16 panResampleState[0x10]; + s16 panSamplesBuffer[0x20]; + s16 dummyResampleState[0x10]; + s16 samples[0x40]; +}; + +struct AudioSessionSettings { + /*0x00*/ u32 frequency; + /*0x04*/ u8 maxSimultaneousNotes; + /*0x05*/ u8 reverbDownsampleRate; // always 1 + /*0x06*/ u16 reverbWindowSize; + /*0x08*/ u16 reverbGain; + /*0x0A*/ u16 volume; + /*0x0C*/ u32 persistentSeqMem; + /*0x10*/ u32 persistentBankMem; + /*0x14*/ u32 temporarySeqMem; + /*0x18*/ u32 temporaryBankMem; +}; // size = 0x1C + +#endif // AUDIO_INTERNAL_H diff --git a/src/audio/load.c b/src/audio/us_jp/load.c similarity index 80% rename from src/audio/load.c rename to src/audio/us_jp/load.c index aa0c71d9..c3a886c2 100644 --- a/src/audio/load.c +++ b/src/audio/us_jp/load.c @@ -1,9 +1,7 @@ -#if !defined(VERSION_SH) && !defined(VERSION_CN) #include #include #include "data.h" -#include "external.h" #include "heap.h" #include "load.h" #include "seqplayer.h" @@ -20,15 +18,8 @@ struct SharedDma { /*0xE*/ u8 ttl; // duration after which the DMA can be discarded }; // size = 0x10 -// EU only -void port_eu_init(void); - struct Note *gNotes; -#if defined(VERSION_EU) -UNUSED static u8 pad[4]; -#endif - struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; @@ -46,19 +37,17 @@ OSMesg gAudioDmaMesg; OSIoMesg gAudioDmaIoMesg; struct SharedDma sSampleDmas[0x60]; -u32 gSampleDmaNumListItems; // sh: 0x803503D4 -u32 sSampleDmaListSize1; // sh: 0x803503D8 -u32 sUnused80226B40; // set to 0, never read, sh: 0x803503DC +u32 gSampleDmaNumListItems; +u32 sSampleDmaListSize1; +u32 sUnused80226B40; // set to 0, never read // Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256. u8 sSampleDmaReuseQueue1[256]; u8 sSampleDmaReuseQueue2[256]; u8 sSampleDmaReuseQueueTail1; u8 sSampleDmaReuseQueueTail2; -u8 sSampleDmaReuseQueueHead1; // sh: 0x803505E2 -u8 sSampleDmaReuseQueueHead2; // sh: 0x803505E3 - -// bss correct up to here +u8 sSampleDmaReuseQueueHead1; +u8 sSampleDmaReuseQueueHead2; ALSeqFile *gSeqFileHeader; ALSeqFile *gAlCtlHeader; @@ -66,36 +55,23 @@ ALSeqFile *gAlTbl; u8 *gAlBankSets; u16 gSequenceCount; -struct CtlEntry *gCtlEntries; // sh: 0x803505F8 +struct CtlEntry *gCtlEntries; -#if defined(VERSION_EU) -u32 padEuBss1; -struct AudioBufferParametersEU gAudioBufferParameters; -#else s32 gAiFrequency; -#endif u32 sDmaBufSize; s32 gMaxAudioCmds; s32 gMaxSimultaneousNotes; -#if defined(VERSION_EU) -s16 gTempoInternalToExternal; -#else s32 gSamplesPerFrameTarget; s32 gMinAiBufferLength; s16 gTempoInternalToExternal; s8 gAudioUpdatesPerFrame; -#endif s8 gSoundMode; -#if defined(VERSION_EU) -s8 gAudioUpdatesPerFrame; -#endif - extern u64 gAudioGlobalsStartMarker; extern u64 gAudioGlobalsEndMarker; @@ -118,25 +94,6 @@ void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { eu_stubbed_printf_0("Romcopyend\n"); } -#ifdef VERSION_EU -u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d"; -u8 audioString35[] = "BASE %x %x\n"; -u8 audioString36[] = "LOAD %x %x %x\n"; -u8 audioString37[] = "INSTTOP %x\n"; -u8 audioString38[] = "INSTMAP[0] %x\n"; -u8 audioString39[] = "already flags %d\n"; -u8 audioString40[] = "already flags %d\n"; -u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n"; -u8 audioString42[] = "ERR:SLOW DMA BUSY\n"; -u8 audioString43[] = "Check %d bank %d\n"; -u8 audioString44[] = "Cache Check\n"; -u8 audioString45[] = "NO BANK ERROR\n"; -u8 audioString46[] = "BANK %d LOADING START\n"; -u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n"; -u8 audioString48[] = "BANK %d ALREADY CACHED\n"; -u8 audioString49[] = "BANK LOAD MISS! FOR %d\n"; -#endif - /** * Performs an asynchronus (normal priority) DMA copy */ @@ -150,11 +107,7 @@ void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQ * to 0x1000 bytes transfer at once. */ void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { -#if defined(VERSION_EU) - ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining); -#else ssize_t transfer = (*remaining < 0x1000 ? *remaining : 0x1000); -#endif *remaining -= transfer; osInvalDCache(*vAddr, transfer); osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, *devAddr, *vAddr, transfer, queue); @@ -166,11 +119,7 @@ void decrease_sample_dma_ttls() { u32 i; for (i = 0; i < sSampleDmaListSize1; i++) { -#if defined(VERSION_EU) - struct SharedDma *temp = &sSampleDmas[i]; -#else struct SharedDma *temp = sSampleDmas + i; -#endif if (temp->ttl != 0) { temp->ttl--; if (temp->ttl == 0) { @@ -181,11 +130,7 @@ void decrease_sample_dma_ttls() { } for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { -#if defined(VERSION_EU) - struct SharedDma *temp = &sSampleDmas[i]; -#else struct SharedDma *temp = sSampleDmas + i; -#endif if (temp->ttl != 0) { temp->ttl--; if (temp->ttl == 0) { @@ -210,11 +155,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) { for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { -#if defined(VERSION_EU) - dma = &sSampleDmas[i]; -#else dma = sSampleDmas + i; -#endif bufferPos = devAddr - dma->source; if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { // We already have a DMA request for this memory range. @@ -231,11 +172,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { } dma->ttl = 60; *dmaIndexRef = (u8) i; -#if defined(VERSION_EU) - return &dma->buffer[(devAddr - dma->source)]; -#else return (devAddr - dma->source) + dma->buffer; -#endif } } @@ -248,12 +185,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { hasDma = TRUE; } } else { -#if defined(VERSION_EU) - dma = sSampleDmas; - dma += *dmaIndexRef; -#else dma = sSampleDmas + *dmaIndexRef; -#endif bufferPos = devAddr - dma->source; if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { // We already have DMA for this memory range. @@ -261,10 +193,6 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { // Move the DMA out of the reuse queue, by swapping it with the // tail, and then incrementing the tail. if (dma->reuseIndex != sSampleDmaReuseQueueTail1) { -#if defined(VERSION_EU) - if (1) { - } -#endif sSampleDmaReuseQueue1[dma->reuseIndex] = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]; sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex = @@ -273,11 +201,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { sSampleDmaReuseQueueTail1++; } dma->ttl = 2; -#if defined(VERSION_EU) - return dma->buffer + (devAddr - dma->source); -#else return (devAddr - dma->source) + dma->buffer; -#endif } } @@ -297,48 +221,25 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { #ifdef VERSION_US osInvalDCache(dma->buffer, transfer); #endif -#if defined(VERSION_EU) - osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, - OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); - *dmaIndexRef = dmaIndex; - return (devAddr - dmaDevAddr) + dma->buffer; -#else gCurrAudioFrameDmaCount++; osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount - 1], OS_MESG_PRI_NORMAL, OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); *dmaIndexRef = dmaIndex; return dma->buffer + (devAddr - dmaDevAddr); -#endif } void init_sample_dma_buffers(UNUSED s32 arg0) { s32 i; -#if defined(VERSION_EU) -#define j i -#else s32 j; -#endif -#if defined(VERSION_EU) - sDmaBufSize = 0x400; -#else sDmaBufSize = 144 * 9; -#endif -#if defined(VERSION_EU) - for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) -#else for (i = 0; i < gMaxSimultaneousNotes * 3; i++) -#endif { sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { -#if defined(VERSION_EU) - break; -#else goto out1; -#endif } sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; sSampleDmas[gSampleDmaNumListItems].source = 0; @@ -347,9 +248,7 @@ void init_sample_dma_buffers(UNUSED s32 arg0) { sSampleDmas[gSampleDmaNumListItems].ttl = 0; gSampleDmaNumListItems++; } -#if defined(VERSION_JP) || defined(VERSION_US) out1: -#endif for (i = 0; (u32) i < gSampleDmaNumListItems; i++) { sSampleDmaReuseQueue1[i] = (u8) i; @@ -364,19 +263,11 @@ out1: sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems; sSampleDmaListSize1 = gSampleDmaNumListItems; -#if defined(VERSION_EU) - sDmaBufSize = 0x200; -#else sDmaBufSize = 160 * 9; -#endif for (i = 0; i < gMaxSimultaneousNotes; i++) { sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { -#if defined(VERSION_EU) - break; -#else goto out2; -#endif } sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; sSampleDmas[gSampleDmaNumListItems].source = 0; @@ -385,9 +276,7 @@ out1: sSampleDmas[gSampleDmaNumListItems].ttl = 0; gSampleDmaNumListItems++; } -#if defined(VERSION_JP) || defined(VERSION_US) out2: -#endif for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) { sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i; @@ -402,15 +291,10 @@ out2: sSampleDmaReuseQueueTail2 = 0; sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1; -#if defined(VERSION_EU) -#undef j -#endif } -#if defined(VERSION_JP) || defined(VERSION_US) // This function gets optimized out on US due to being static and never called UNUSED static -#endif void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED u8 *offsetBase) { struct AudioBankSample *sample; void *patched; @@ -426,30 +310,11 @@ void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED sample->book = PATCH(sample->book, memBase); sample->loaded = 1; } -#if defined(VERSION_EU) - else if (sample->loaded == 0x80) { - PATCH(sample->sampleAddr, offsetBase); - mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); - if (mem == NULL) { - sample->sampleAddr = patched; - sample->loaded = 1; - } else { - audio_dma_copy_immediate((uintptr_t) patched, mem, sample->sampleSize); - sample->loaded = 0x81; - sample->sampleAddr = mem; - } - sample->loop = PATCH(sample->loop, memBase); - sample->book = PATCH(sample->book, memBase); - } -#endif } #undef PATCH } -#ifdef VERSION_EU -#define PATCH_SOUND patch_sound -#else // copt inline of the above #define PATCH_SOUND(_sound, mem, offset) \ { \ @@ -473,9 +338,8 @@ void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED } \ } \ } -#endif -// on US/JP this inlines patch_sound, using some -sopt compiler flag +// This inlines patch_sound using some -sopt compiler flag void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { struct Instrument *instrument; struct Instrument **itInstrs; @@ -485,58 +349,36 @@ void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 void *patched; struct Drum *drum; struct Drum **drums; -#if defined(VERSION_EU) - u32 numDrums2; -#endif #define BASE_OFFSET_REAL(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) #define PATCH(x, base) (patched = BASE_OFFSET_REAL(x, base)) #define PATCH_MEM(x) x = PATCH(x, mem) -#if defined(VERSION_JP) || defined(VERSION_US) #define BASE_OFFSET(x, base) BASE_OFFSET_REAL(x, base) -#else -#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(base, x) -#endif drums = mem->drums; -#if defined(VERSION_JP) || defined(VERSION_US) if (drums != NULL && numDrums > 0) { mem->drums = (void *)((uintptr_t) drums + (uintptr_t) mem); if (numDrums > 0) //! unneeded when -sopt is enabled for (i = 0; i < numDrums; i++) { -#else - numDrums2 = numDrums; - if (drums != NULL && numDrums2 > 0) { - mem->drums = PATCH(drums, mem); - for (i = 0; i < numDrums2; i++) { -#endif patched = mem->drums[i]; if (patched != NULL) { drum = PATCH(patched, mem); mem->drums[i] = drum; if (drum->loaded == 0) { -#if defined(VERSION_JP) || defined(VERSION_US) //! copt replaces drum with 'patched' for these two lines PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset); patched = (*(struct Drum *)patched).envelope; -#else - patch_sound(&drum->sound, (u8 *) mem, offset); - patched = drum->envelope; -#endif drum->envelope = BASE_OFFSET(mem, patched); drum->loaded = 1; } - } } } //! Doesn't affect EU, but required for US/JP temp = &*mem; -#if defined(VERSION_JP) || defined(VERSION_US) if (numInstruments >= 1) -#endif if (numInstruments > 0) { //! Doesn't affect EU, but required for US/JP struct Instrument **tempInst; @@ -544,11 +386,7 @@ void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 tempInst = temp->instruments; end = numInstruments + tempInst; -#if defined(VERSION_JP) || defined(VERSION_US) l2: -#else - do { -#endif if (*itInstrs != NULL) { *itInstrs = BASE_OFFSET(*itInstrs, mem); instrument = *itInstrs; @@ -563,14 +401,10 @@ l2: } } itInstrs++; -#if defined(VERSION_JP) || defined(VERSION_US) - //! goto generated by copt, required to match US/JP + //! goto generated by copt, required to match if (end != itInstrs) { goto l2; } -#else - } while (end != itInstrs); -#endif } #undef PATCH_MEM #undef PATCH @@ -620,9 +454,6 @@ struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *s struct AudioBank *ret; u8 *ctlData; OSMesgQueue *mesgQueue; -#if defined(VERSION_EU) - UNUSED u32 pad3; -#endif alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; alloc = ALIGN16(alloc); @@ -637,29 +468,15 @@ struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *s numInstruments = buf[0]; numDrums = buf[1]; seqPlayer->loadingBankId = (u8) bankId; -#if defined(VERSION_EU) - gCtlEntries[bankId].numInstruments = numInstruments; - gCtlEntries[bankId].numDrums = numDrums; - gCtlEntries[bankId].instruments = ret->instruments; - gCtlEntries[bankId].drums = 0; - seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; - seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); - seqPlayer->bankDmaRemaining = alloc; - if (1) { - } -#else seqPlayer->loadingBankNumInstruments = numInstruments; seqPlayer->loadingBankNumDrums = numDrums; seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; seqPlayer->loadingBank = ret; seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); seqPlayer->bankDmaRemaining = alloc; -#endif mesgQueue = &seqPlayer->bankDmaMesgQueue; osCreateMesgQueue(mesgQueue, &seqPlayer->bankDmaMesg, 1); -#if defined(VERSION_JP) || defined(VERSION_US) seqPlayer->bankDmaMesg = NULL; -#endif seqPlayer->bankDmaInProgress = TRUE; audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, &seqPlayer->bankDmaRemaining, mesgQueue, &seqPlayer->bankDmaIoMesg); @@ -711,9 +528,7 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40); mesgQueue = &seqPlayer->seqDmaMesgQueue; osCreateMesgQueue(mesgQueue, &seqPlayer->seqDmaMesg, 1); -#if defined(VERSION_JP) || defined(VERSION_US) seqPlayer->seqDmaMesg = NULL; -#endif seqPlayer->seqDmaInProgress = TRUE; audio_dma_copy_async((uintptr_t)(seqData + 0x40), (u8 *) ptr + 0x40, seqLength - 0x40, mesgQueue, &seqPlayer->seqDmaIoMesg); @@ -731,23 +546,13 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { *nullCount = 0; *nonNullCount = 0; -#if defined(VERSION_EU) - offset = ((u16 *) gAlBankSets)[seqId]; - for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) { - bankId = gAlBankSets[offset++]; -#else offset = ((u16 *) gAlBankSets)[seqId] + 1; for (i = gAlBankSets[offset - 1], ret = 0; i != 0; i--) { offset++; bankId = gAlBankSets[offset - 1]; -#endif if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { -#if defined(VERSION_EU) - temp = get_bank_or_seq(&gBankLoadedPool, 2, bankId); -#else temp = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); -#endif } else { temp = NULL; } @@ -770,22 +575,13 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { u8 i; offset = ((u16 *) gAlBankSets)[seqId]; -#ifdef VERSION_EU - for (i = gAlBankSets[offset++]; i != 0; i--) { - bankId = gAlBankSets[offset++]; -#else offset++; for (i = gAlBankSets[offset - 1]; i != 0; i--) { offset++; bankId = gAlBankSets[offset - 1]; -#endif if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { -#ifdef VERSION_EU - ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId); -#else ret = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); -#endif } else { ret = NULL; } @@ -906,30 +702,17 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { // (void) must be omitted from parameters to fix stack with -framepointer void audio_init() { -#if defined(VERSION_EU) - UNUSED s8 pad[16]; -#else UNUSED s8 pad[32]; -#endif -#if defined(VERSION_JP) || defined(VERSION_US) u8 buf[0x10]; -#endif s32 i, j, k; - UNUSED s32 lim1; // lim1 unused in EU -#if defined(VERSION_EU) - UNUSED u8 buf[0x10]; - s32 UNUSED lim2, lim3; -#else - s32 lim2, lim3; -#endif - UNUSED u32 size; + s32 lim1, lim2, lim3; + u32 size; UNUSED u64 *ptr64; void *data; UNUSED s32 pad2; gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; -#if defined(VERSION_JP) || defined(VERSION_US) lim1 = gUnusedCount80333EE8; for (i = 0; i < lim1; i++) { gUnused80226E58[i] = 0; @@ -952,27 +735,6 @@ void audio_init() { } #endif -#else - for (i = 0; i < gAudioHeapSize / 8; i++) { - ((u64 *) gAudioHeap)[i] = 0; - } - -#ifdef TARGET_N64 - // It seems boot.s doesn't clear the .bss area for audio, so do it here. - lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; - ptr64 = &gAudioGlobalsStartMarker; - for (k = lim3; k >= 0; k--) { - *ptr64++ = 0; - } -#endif - - D_EU_802298D0 = 20.03042f; - gRefreshRate = 50; - port_eu_init(); - if (k) { - } -#endif - #ifdef TARGET_N64 eu_stubbed_printf_3( "Clear Workarea %x -%x size %x \n", @@ -1011,13 +773,7 @@ void audio_init() { } } -#if defined(VERSION_EU) - gAudioResetPresetIdToLoad = 0; - gAudioResetStatus = 1; - audio_shut_down_and_reset_step(); -#else audio_reset_session(&gAudioSessionPresets[0]); -#endif // Not sure about these prints eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0); @@ -1029,12 +785,7 @@ void audio_init() { data = gMusicData; audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10); gSequenceCount = gSeqFileHeader->seqCount; -#if defined(VERSION_EU) - size = gSequenceCount * sizeof(ALSeqData) + 4; - size = ALIGN16(size); -#else size = ALIGN16(gSequenceCount * sizeof(ALSeqData) + 4); -#endif gSeqFileHeader = soundAlloc(&gAudioInitPool, size); audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size); alSeqFileNew(gSeqFileHeader, data); @@ -1073,4 +824,3 @@ void audio_init() { eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw eu_stubbed_printf_0("---------------------------------------\n"); } -#endif diff --git a/src/audio/us_jp/load.h b/src/audio/us_jp/load.h new file mode 100644 index 00000000..cfcec76b --- /dev/null +++ b/src/audio/us_jp/load.h @@ -0,0 +1,57 @@ +#ifndef AUDIO_LOAD_H +#define AUDIO_LOAD_H + +#include + +#include "internal.h" + +#define AUDIO_FRAME_DMA_QUEUE_SIZE 0x40 + +#define PRELOAD_BANKS 2 +#define PRELOAD_SEQUENCE 1 + +#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t)(ptr) != (uintptr_t)&gSequenceChannelNone) + +extern struct Note *gNotes; + +// Music in SM64 is played using 3 players: +// gSequencePlayers[0] is level background music +// gSequencePlayers[1] is misc music, like the puzzle jingle +// gSequencePlayers[2] is sound +extern struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; + +extern struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +extern struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; + +extern struct SequenceChannel gSequenceChannelNone; + +extern struct AudioListItem gLayerFreeList; +extern struct NotePool gNoteFreeLists; + +extern OSMesgQueue gCurrAudioFrameDmaQueue; +extern u32 gSampleDmaNumListItems; +extern ALSeqFile *gAlCtlHeader; +extern ALSeqFile *gAlTbl; +extern ALSeqFile *gSeqFileHeader; +extern u8 *gAlBankSets; + +extern struct CtlEntry *gCtlEntries; +extern s32 gAiFrequency; +extern s32 gMaxAudioCmds; + +extern s32 gMaxSimultaneousNotes; +extern s32 gSamplesPerFrameTarget; +extern s32 gMinAiBufferLength; +extern s16 gTempoInternalToExternal; +extern s8 gAudioUpdatesPerFrame; // = 4 +extern s8 gSoundMode; + +void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg); +void decrease_sample_dma_ttls(void); +void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef); +void init_sample_dma_buffers(s32 arg0); +void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums); +void preload_sequence(u32 seqId, u8 preloadMask); +void load_sequence(u32 player, u32 seqId, s32 loadAsync); + +#endif // AUDIO_LOAD_H diff --git a/src/audio/us_jp/playback.c b/src/audio/us_jp/playback.c new file mode 100644 index 00000000..59208b60 --- /dev/null +++ b/src/audio/us_jp/playback.c @@ -0,0 +1,629 @@ +#include + +#include "heap.h" +#include "data.h" +#include "load.h" +#include "seqplayer.h" +#include "playback.h" +#include "synthesis.h" +#include "effects.h" + +void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput); + +s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); + +void note_init(struct Note *note) { + if (note->parentLayer->adsr.releaseRate == 0) { + adsr_init(¬e->adsr, note->parentLayer->seqChannel->adsr.envelope, ¬e->adsrVolScale); + } else { + adsr_init(¬e->adsr, note->parentLayer->adsr.envelope, ¬e->adsrVolScale); + } + note->adsr.state = ADSR_STATE_INITIAL; + note_init_volume(note); + note_enable(note); +} + +void note_disable2(struct Note *note) { + note_disable(note); +} + +void process_notes(void) { + f32 scale; + f32 frequency; + u8 reverbVol; + f32 velocity; + f32 pan; + f32 cap; + struct Note *note; + struct NoteAttributes *attributes; + struct AudioListItem *it; + s32 i; + + // Macro versions of audio_list_push_front and audio_list_remove. + // Should ideally be changed to use copt. +#define PREPEND(item, head_arg) \ + ((it = (item), it->prev != NULL) \ + ? it \ + : (it->prev = (head_arg), it->next = (head_arg)->next, (head_arg)->next->prev = it, \ + (head_arg)->next = it, (head_arg)->u.count++, it->pool = (head_arg)->pool, it)) +#define POP(item) \ + ((it = (item), it->prev == NULL) \ + ? it \ + : (it->prev->next = it->next, it->next->prev = it->prev, it->prev = NULL, it)) + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + if (note->priority != NOTE_PRIORITY_DISABLED) { + if (note->priority == NOTE_PRIORITY_STOPPING || note->finished) { + if (note->adsrVolScale == 0 || note->finished) { + if (note->wantedParentLayer != NO_LAYER) { + note_disable2(note); + if (note->wantedParentLayer->seqChannel != NULL) { + if (note_init_for_layer(note, note->wantedParentLayer) == TRUE) { + note_disable2(note); + POP(¬e->listItem); + PREPEND(¬e->listItem, &gNoteFreeLists.disabled); + } else { + note_vibrato_init(note); + audio_list_push_back(¬e->listItem.pool->active, + POP(¬e->listItem)); + note->wantedParentLayer = NO_LAYER; + } + } else { + note_disable2(note); + audio_list_push_back(¬e->listItem.pool->disabled, POP(¬e->listItem)); + note->wantedParentLayer = NO_LAYER; + continue; + } + } else { + note_disable2(note); + audio_list_push_back(¬e->listItem.pool->disabled, POP(¬e->listItem)); + continue; + } + } + } else { + if (note->adsr.state == ADSR_STATE_DISABLED) { + note_disable2(note); + audio_list_push_back(¬e->listItem.pool->disabled, POP(¬e->listItem)); + continue; + } + } + + adsr_update(¬e->adsr); + note_vibrato_update(note); + attributes = ¬e->attributes; + if (note->priority == NOTE_PRIORITY_STOPPING) { + frequency = attributes->freqScale; + velocity = attributes->velocity; + pan = attributes->pan; + reverbVol = attributes->reverbVol; + } else { + frequency = note->parentLayer->noteFreqScale; + velocity = note->parentLayer->noteVelocity; + pan = note->parentLayer->notePan; + reverbVol = note->parentLayer->seqChannel->reverbVol; + } + + scale = note->adsrVolScale; + frequency *= note->vibratoFreqScale * note->portamentoFreqScale; + cap = 3.99992f; + if (gAiFrequency != 32006) { + frequency *= JP_DOUBLE(32000.0) / (f32) gAiFrequency; + } + frequency = (frequency < cap ? frequency : cap); + scale *= 4.3498e-5f; // ~1 / 23000 + velocity = velocity * scale * scale; + note_set_frequency(note, frequency); + note_set_vel_pan_reverb(note, velocity, pan, reverbVol); + continue; + } + } +#undef PREPEND +#undef POP +} + +void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLayer, s32 target) { + struct Note *note; + struct NoteAttributes *attributes; + + if (seqLayer == NO_LAYER) { + return; + } + + if (seqLayer->note == NULL) { + return; + } + + note = seqLayer->note; + attributes = ¬e->attributes; + + if (seqLayer->seqChannel != NULL && seqLayer->seqChannel->noteAllocPolicy == 0) { + seqLayer->note = NULL; + } + + if (note->wantedParentLayer == seqLayer) { + note->wantedParentLayer = NO_LAYER; + } + + if (note->parentLayer != seqLayer) { + + return; + } + + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + if (note->adsr.state != ADSR_STATE_DECAY) { + attributes->freqScale = seqLayer->noteFreqScale; + attributes->velocity = seqLayer->noteVelocity; + attributes->pan = seqLayer->notePan; + if (seqLayer->seqChannel != NULL) { + attributes->reverbVol = seqLayer->seqChannel->reverbVol; + } + note->priority = NOTE_PRIORITY_STOPPING; + note->prevParentLayer = note->parentLayer; + note->parentLayer = NO_LAYER; + if (target == ADSR_STATE_RELEASE) { + note->adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; + note->adsr.action |= ADSR_ACTION_RELEASE; + } else { + note->adsr.action |= ADSR_ACTION_DECAY; + if (seqLayer->adsr.releaseRate == 0) { + note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * 24; + } else { + note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * 24; + } + note->adsr.sustain = (note->adsr.current * seqLayer->seqChannel->adsr.sustain) / 0x10000; + } + } + + if (target == ADSR_STATE_DECAY) { + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); + } +} + +void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_DECAY); +} + +void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_RELEASE); +} + +void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { + s32 i; + s32 j; + s32 pos; + s32 stepSize; + s32 offset; + u8 lim; + u8 origSampleCount = note->sampleCount; + + if (seqLayer->freqScale < JP_DOUBLE(1.0)) { + note->sampleCount = 64; + seqLayer->freqScale *= JP_DOUBLE(1.0465); + stepSize = 1; + } else if (seqLayer->freqScale < JP_DOUBLE(2.0)) { + note->sampleCount = 32; + seqLayer->freqScale *= JP_DOUBLE(0.52325); + stepSize = 2; + } else if (seqLayer->freqScale < JP_DOUBLE(4.0)) { + note->sampleCount = 16; + seqLayer->freqScale *= JP_DOUBLE(0.26263); + stepSize = 4; + } else { + note->sampleCount = 8; + seqLayer->freqScale *= JP_DOUBLE(0.13081); + stepSize = 8; + } + + if (note->sampleCount == origSampleCount && seqLayer->seqChannel->instOrWave == note->instOrWave) { + return; + } + + // Load wave sample + note->instOrWave = (u8) seqLayer->seqChannel->instOrWave; + for (i = -1, pos = 0; pos < 0x40; pos += stepSize) { + i++; + note->synthesisBuffers->samples[i] = gWaveSamples[seqLayer->seqChannel->instOrWave - 0x80][pos]; + } + + // Repeat sample + for (offset = note->sampleCount; offset < 0x40; offset += note->sampleCount) { + lim = note->sampleCount; + if (offset < 0 || offset > 0) { + for (j = 0; j < lim; j++) { + note->synthesisBuffers->samples[offset + j] = note->synthesisBuffers->samples[j]; + } + } else { + for (j = 0; j < lim; j++) { + note->synthesisBuffers->samples[offset + j] = note->synthesisBuffers->samples[j]; + } + } + } + + osWritebackDCache(note->synthesisBuffers->samples, sizeof(note->synthesisBuffers->samples)); +} + +void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { + s32 sampleCount = note->sampleCount; + build_synthetic_wave(note, seqLayer); + if (sampleCount != 0) { + note->samplePosInt *= note->sampleCount / sampleCount; + } else { + note->samplePosInt = 0; + } +} + +void init_note_list(struct AudioListItem *list) { + list->prev = list; + list->next = list; + list->u.count = 0; +} + +void init_note_lists(struct NotePool *pool) { + init_note_list(&pool->disabled); + init_note_list(&pool->decaying); + init_note_list(&pool->releasing); + init_note_list(&pool->active); + pool->disabled.pool = pool; + pool->decaying.pool = pool; + pool->releasing.pool = pool; + pool->active.pool = pool; +} + +void init_note_free_list(void) { + s32 i; + + init_note_lists(&gNoteFreeLists); + for (i = 0; i < gMaxSimultaneousNotes; i++) { + gNotes[i].listItem.u.value = &gNotes[i]; + gNotes[i].listItem.prev = NULL; + audio_list_push_back(&gNoteFreeLists.disabled, &gNotes[i].listItem); + } +} + +void note_pool_clear(struct NotePool *pool) { + s32 i; + struct AudioListItem *source; + struct AudioListItem *cur; + struct AudioListItem *dest; + s32 j; + + for (i = 0; i < 4; i++) { + switch (i) { + case 0: + source = &pool->disabled; + dest = &gNoteFreeLists.disabled; + break; + + case 1: + source = &pool->decaying; + dest = &gNoteFreeLists.decaying; + break; + + case 2: + source = &pool->releasing; + dest = &gNoteFreeLists.releasing; + break; + + case 3: + source = &pool->active; + dest = &gNoteFreeLists.active; + break; + } + + j = 0; + do { + cur = source->next; + if (cur == source) { + break; + } + audio_list_remove(cur); + audio_list_push_back(dest, cur); + j++; + } while (j <= gMaxSimultaneousNotes); + } +} + +void note_pool_fill(struct NotePool *pool, s32 count) { + s32 i; + s32 j; + struct Note *note; + struct AudioListItem *source; + struct AudioListItem *dest; + + note_pool_clear(pool); + + for (i = 0, j = 0; j < count; i++) { + if (i == 4) { + eu_stubbed_printf_1("Alloc Error:Dim voice-Alloc %d", count); + return; + } + + switch (i) { + case 0: + source = &gNoteFreeLists.disabled; + dest = &pool->disabled; + break; + + case 1: + source = &gNoteFreeLists.decaying; + dest = &pool->decaying; + break; + + case 2: + source = &gNoteFreeLists.releasing; + dest = &pool->releasing; + break; + + case 3: + source = &gNoteFreeLists.active; + dest = &pool->active; + break; + } + + while (j < count) { + note = audio_list_pop_back(source); + if (note == NULL) { + break; + } + audio_list_push_back(dest, ¬e->listItem); + j++; + } + } +} + +void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item) { + // add 'item' to the front of the list given by 'list', if it's not in any list + if (item->prev != NULL) { + eu_stubbed_printf_0("Error:Same List Add\n"); + } else { + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; + list->u.count++; + item->pool = list->pool; + } +} + +void audio_list_remove(struct AudioListItem *item) { + // remove 'item' from the list it's in, if any + if (item->prev == NULL) { + eu_stubbed_printf_0("Already Cut\n"); + } else { + item->prev->next = item->next; + item->next->prev = item->prev; + item->prev = NULL; + } +} + +struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) { + struct AudioListItem *cur = list->next; + struct AudioListItem *best; + + if (cur == list) { + return NULL; + } + + for (best = cur; cur != list; cur = cur->next) { + if (((struct Note *) best->u.value)->priority >= ((struct Note *) cur->u.value)->priority) { + best = cur; + } + } + + if (limit < ((struct Note *) best->u.value)->priority) { + return NULL; + } + + audio_list_remove(best); + return best->u.value; +} + +s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { + note->prevParentLayer = NO_LAYER; + note->parentLayer = seqLayer; + note->priority = seqLayer->seqChannel->notePriority; + if (IS_BANK_LOAD_COMPLETE(seqLayer->seqChannel->bankId) == FALSE) { + return TRUE; + } + + note->bankId = seqLayer->seqChannel->bankId; + note->stereoHeadsetEffects = seqLayer->seqChannel->stereoHeadsetEffects; + note->sound = seqLayer->sound; + seqLayer->status = SOUND_LOAD_STATUS_DISCARDABLE; // "loaded" + seqLayer->note = note; + seqLayer->seqChannel->noteUnused = note; + seqLayer->seqChannel->layerUnused = seqLayer; + if (note->sound == NULL) { + build_synthetic_wave(note, seqLayer); + } + note_init(note); + return FALSE; +} + +void func_80319728(struct Note *note, struct SequenceChannelLayer *seqLayer) { + seq_channel_layer_note_release(note->parentLayer); + note->wantedParentLayer = seqLayer; +} + +void note_release_and_take_ownership(struct Note *note, struct SequenceChannelLayer *seqLayer) { + note->wantedParentLayer = seqLayer; + note->priority = NOTE_PRIORITY_STOPPING; + + note->adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; + note->adsr.action |= ADSR_ACTION_RELEASE; +} + +struct Note *alloc_note_from_disabled(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *note = audio_list_pop_back(&pool->disabled); + if (note != NULL) { + if (note_init_for_layer(note, seqLayer) == TRUE) { + audio_list_push_front(&gNoteFreeLists.disabled, ¬e->listItem); + return NULL; + } + audio_list_push_front(&pool->active, ¬e->listItem); + } + return note; +} + +struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *note = audio_list_pop_back(&pool->decaying); + if (note != NULL) { + note_release_and_take_ownership(note, seqLayer); + audio_list_push_back(&pool->releasing, ¬e->listItem); + } + return note; +} + +struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { + struct Note *aNote; + + aNote = pop_node_with_lower_prio(&pool->active, seqLayer->seqChannel->notePriority); + + if (aNote == NULL) { + eu_stubbed_printf_0("Audio: C-Alloc : lowerPrio is NULL\n"); + } else { + func_80319728(aNote, seqLayer); + audio_list_push_back(&pool->releasing, &aNote->listItem); + } + + return aNote; +} + +struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { + struct Note *ret; + u32 policy = seqLayer->seqChannel->noteAllocPolicy; + + if (policy & NOTE_ALLOC_LAYER) { + ret = seqLayer->note; + if (ret != NULL && ret->prevParentLayer == seqLayer + ) { + note_release_and_take_ownership(ret, seqLayer); + audio_list_remove(&ret->listItem); + audio_list_push_back(&gNoteFreeLists.releasing, &ret->listItem); + return ret; + } + } + + if (policy & NOTE_ALLOC_CHANNEL) { + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) { + eu_stubbed_printf_0("Sub Limited Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; + } + + if (policy & NOTE_ALLOC_SEQ) { + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; + } + + if (policy & NOTE_ALLOC_GLOBAL_FREELIST) { + if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; + } + + if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) + && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { + eu_stubbed_printf_0("Warning: Drop Voice"); + seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; + return NULL; + } + return ret; +} + +void reclaim_notes(void) { + struct Note *note; + s32 i; + s32 cond; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + if (note->parentLayer != NO_LAYER) { + cond = FALSE; + if (!note->parentLayer->enabled && note->priority >= NOTE_PRIORITY_MIN) { + cond = TRUE; + } else if (note->parentLayer->seqChannel == NULL) { + audio_list_push_back(&gLayerFreeList, ¬e->parentLayer->listItem); + seq_channel_layer_disable(note->parentLayer); + note->priority = NOTE_PRIORITY_STOPPING; + } else if (note->parentLayer->seqChannel->seqPlayer == NULL) { + sequence_channel_disable(note->parentLayer->seqChannel); + note->priority = NOTE_PRIORITY_STOPPING; + } else if (note->parentLayer->seqChannel->seqPlayer->muted) { + if (note->parentLayer->seqChannel->muteBehavior + & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES)) { + cond = TRUE; + } + } else { + cond = FALSE; + } + + if (cond) { + seq_channel_layer_note_release(note->parentLayer); + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->disabled, ¬e->listItem); + note->priority = NOTE_PRIORITY_STOPPING; + } + } + } +} + +void note_init_all(void) { + struct Note *note; + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + note = &gNotes[i]; + note->enabled = FALSE; + note->stereoStrongRight = FALSE; + note->stereoStrongLeft = FALSE; + note->stereoHeadsetEffects = FALSE; + note->priority = NOTE_PRIORITY_DISABLED; + note->parentLayer = NO_LAYER; + note->wantedParentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; + note->reverbVol = 0; + note->usesHeadsetPanEffects = FALSE; + note->sampleCount = 0; + note->instOrWave = 0; + note->targetVolLeft = 0; + note->targetVolRight = 0; + note->frequency = 0.0f; + note->unused1 = 0x3f; + note->attributes.velocity = 0.0f; + note->adsrVolScale = 0; + note->adsr.state = ADSR_STATE_DISABLED; + note->adsr.action = 0; + note->vibratoState.active = FALSE; + note->portamento.cur = 0.0f; + note->portamento.speed = 0.0f; + note->synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); + } +} diff --git a/src/audio/us_jp/playback.h b/src/audio/us_jp/playback.h new file mode 100644 index 00000000..a9840e46 --- /dev/null +++ b/src/audio/us_jp/playback.h @@ -0,0 +1,34 @@ +#ifndef AUDIO_PLAYBACK_H +#define AUDIO_PLAYBACK_H + +#include + +#include "internal.h" + +// Mask bits denoting where to allocate notes from, according to a channel's +// noteAllocPolicy. Despite being checked as bitmask bits, the bits are not +// orthogonal; rather, the smallest bit wins, except for NOTE_ALLOC_LAYER, +// which *is* orthogonal to the other. SEQ implicitly includes CHANNEL. +// If none of the CHANNEL/SEQ/GLOBAL_FREELIST bits are set, all three locations +// are tried. +#define NOTE_ALLOC_LAYER 1 +#define NOTE_ALLOC_CHANNEL 2 +#define NOTE_ALLOC_SEQ 4 +#define NOTE_ALLOC_GLOBAL_FREELIST 8 + +void process_notes(void); +void seq_channel_layer_note_decay(struct SequenceChannelLayer *seqLayer); +void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer); +void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer); +void init_note_lists(struct NotePool *pool); +void init_note_free_list(void); +void note_pool_clear(struct NotePool *pool); +void note_pool_fill(struct NotePool *pool, s32 count); +void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item); +void audio_list_remove(struct AudioListItem *item); +struct Note *alloc_note(struct SequenceChannelLayer *seqLayer); +void reclaim_notes(void); +void note_init_all(void); + + +#endif // AUDIO_PLAYBACK_H diff --git a/src/audio/us_jp/seqplayer.c b/src/audio/us_jp/seqplayer.c new file mode 100644 index 00000000..383c19f6 --- /dev/null +++ b/src/audio/us_jp/seqplayer.c @@ -0,0 +1,1617 @@ +#include + +#include "data.h" +#include "effects.h" +#include "heap.h" +#include "load.h" +#include "seqplayer.h" + +#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) +#define PORTAMENTO_MODE(x) ((x).mode & ~0x80) +#define PORTAMENTO_MODE_1 1 +#define PORTAMENTO_MODE_2 2 +#define PORTAMENTO_MODE_3 3 +#define PORTAMENTO_MODE_4 4 +#define PORTAMENTO_MODE_5 5 + +void seq_channel_layer_process_script(struct SequenceChannelLayer *layer); +void sequence_channel_process_script(struct SequenceChannel *seqChannel); +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, + struct AdsrSettings *adsr); + +void sequence_channel_init(struct SequenceChannel *seqChannel) { + s32 i; + + seqChannel->enabled = FALSE; + seqChannel->finished = FALSE; + seqChannel->stopScript = FALSE; + seqChannel->stopSomething2 = FALSE; + seqChannel->hasInstrument = FALSE; + seqChannel->stereoHeadsetEffects = FALSE; + seqChannel->transposition = 0; + seqChannel->largeNotes = FALSE; + seqChannel->scriptState.depth = 0; + seqChannel->volume = 1.0f; + seqChannel->volumeScale = 1.0f; + seqChannel->freqScale = 1.0f; + seqChannel->pan = 0.5f; + seqChannel->panChannelWeight = 1.0f; + seqChannel->noteUnused = NULL; + seqChannel->reverbVol = 0; + seqChannel->notePriority = NOTE_PRIORITY_DEFAULT; + seqChannel->delay = 0; + seqChannel->adsr.envelope = gDefaultEnvelope; + seqChannel->adsr.releaseRate = 0x20; + seqChannel->adsr.sustain = 0; + seqChannel->updatesPerFrameUnused = gAudioUpdatesPerFrame; + seqChannel->vibratoRateTarget = 0x800; + seqChannel->vibratoRateStart = 0x800; + seqChannel->vibratoExtentTarget = 0; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoRateChangeDelay = 0; + seqChannel->vibratoExtentChangeDelay = 0; + seqChannel->vibratoDelay = 0; + + for (i = 0; i < 8; i++) { + seqChannel->soundScriptIO[i] = -1; + } + + seqChannel->unused = FALSE; + init_note_lists(&seqChannel->notePool); +} + +s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { + struct SequenceChannelLayer *layer; + + if (seqChannel->layers[layerIndex] == NULL) { + layer = audio_list_pop_back(&gLayerFreeList); + seqChannel->layers[layerIndex] = layer; + if (layer == NULL) { + seqChannel->layers[layerIndex] = NULL; + return -1; + } + } else { + seq_channel_layer_note_decay(seqChannel->layers[layerIndex]); + } + + layer = seqChannel->layers[layerIndex]; + layer->seqChannel = seqChannel; + layer->adsr = seqChannel->adsr; + layer->adsr.releaseRate = 0; + layer->enabled = TRUE; + layer->stopSomething = FALSE; + layer->continuousNotes = FALSE; + layer->finished = FALSE; + layer->portamento.mode = 0; + layer->scriptState.depth = 0; + layer->status = SOUND_LOAD_STATUS_NOT_LOADED; + layer->noteDuration = 0x80; + layer->transposition = 0; + layer->delay = 0; + layer->duration = 0; + layer->delayUnused = 0; + layer->note = NULL; + layer->instrument = NULL; + layer->velocitySquare = 0.0f; + layer->pan = 0.5f; + return 0; +} + +void seq_channel_layer_disable(struct SequenceChannelLayer *layer) { + if (layer != NULL) { + seq_channel_layer_note_decay(layer); + layer->enabled = FALSE; + layer->finished = TRUE; + } +} + +void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex) { + struct SequenceChannelLayer *layer = seqChannel->layers[layerIndex]; + + if (layer != NULL) { + struct AudioListItem *item = &layer->listItem; + if (item->prev == NULL) { + gLayerFreeList.prev->next = item; + item->prev = gLayerFreeList.prev; + item->next = &gLayerFreeList; + gLayerFreeList.prev = item; + gLayerFreeList.u.count++; + item->pool = gLayerFreeList.pool; + } + seq_channel_layer_disable(layer); + seqChannel->layers[layerIndex] = NULL; + } +} + +void sequence_channel_disable(struct SequenceChannel *seqChannel) { + s32 i; + for (i = 0; i < LAYERS_MAX; i++) { + seq_channel_layer_free(seqChannel, i); + } + + note_pool_clear(&seqChannel->notePool); + seqChannel->enabled = FALSE; + seqChannel->finished = TRUE; +} + +struct SequenceChannel *allocate_sequence_channel(void) { + s32 i; + for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { + if (gSequenceChannels[i].seqPlayer == NULL) { + return gSequenceChannels + i; + } + } + return &gSequenceChannelNone; +} + +void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channelBits) { + struct SequenceChannel *seqChannel; + s32 i; + + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE && seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; + } + seqChannel = allocate_sequence_channel(); + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + eu_stubbed_printf_0("Audio:Track:Warning: No Free Notetrack\n"); + gAudioErrorFlags = i + 0x10000; + seqPlayer->channels[i] = seqChannel; + } else { + sequence_channel_init(seqChannel); + seqPlayer->channels[i] = seqChannel; + seqChannel->seqPlayer = seqPlayer; + seqChannel->bankId = seqPlayer->defaultBank[0]; + seqChannel->muteBehavior = seqPlayer->muteBehavior; + seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy; + } + } + channelBits >>= 1; + } +} + +void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 channelBits) { + struct SequenceChannel *seqChannel; + s32 i; + + eu_stubbed_printf_0("SUBTRACK DIM\n"); + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE) { + if (seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; + } + seqPlayer->channels[i] = &gSequenceChannelNone; + } + } + channelBits >>= 1; + } +} + +void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script) { + struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; + s32 i; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + } else { + seqChannel->enabled = TRUE; + seqChannel->finished = FALSE; + seqChannel->scriptState.depth = 0; + seqChannel->scriptState.pc = script; + seqChannel->delay = 0; + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != NULL) { + seq_channel_layer_free(seqChannel, i); + } + } + } +} + +void sequence_player_disable(struct SequencePlayer *seqPlayer) { + sequence_player_disable_channels(seqPlayer, 0xffff); + note_pool_clear(&seqPlayer->notePool); + seqPlayer->finished = TRUE; + seqPlayer->enabled = FALSE; + + if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) + ) { + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_DISCARDABLE; + } + + if (IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) + ) { + gBankLoadStatus[seqPlayer->defaultBank[0]] = SOUND_LOAD_STATUS_DISCARDABLE; + } + + // (Note that if this is called from alloc_bank_or_seq, the side will get swapped + // later in that function. Thus, we signal that we want to load into the slot + // of the bank that we no longer need.) + if (gBankLoadedPool.temporary.entries[0].id == seqPlayer->defaultBank[0]) { + gBankLoadedPool.temporary.nextSide = 1; + } else if (gBankLoadedPool.temporary.entries[1].id == seqPlayer->defaultBank[0]) { + gBankLoadedPool.temporary.nextSide = 0; + } +} + +/** + * Add an item to the end of a list, if it's not already in any list. + */ +void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item) { + if (item->prev != NULL) { + eu_stubbed_printf_0("Error:Same List Add\n"); + } else { + list->prev->next = item; + item->prev = list->prev; + item->next = list; + list->prev = item; + list->u.count++; + item->pool = list->pool; + } +} + +/** + * Remove the last item from a list, and return it (or NULL if empty). + */ +void *audio_list_pop_back(struct AudioListItem *list) { + struct AudioListItem *item = list->prev; + if (item == list) { + return NULL; + } + item->prev->next = list; + list->prev = item->prev; + item->prev = NULL; + list->u.count--; + return item->u.value; +} + +void init_layer_freelist(void) { + s32 i; + + gLayerFreeList.prev = &gLayerFreeList; + gLayerFreeList.next = &gLayerFreeList; + gLayerFreeList.u.count = 0; + gLayerFreeList.pool = NULL; + + for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { + gSequenceLayers[i].listItem.u.value = gSequenceLayers + i; + gSequenceLayers[i].listItem.prev = NULL; + audio_list_push_back(&gLayerFreeList, &gSequenceLayers[i].listItem); + } +} + +u8 m64_read_u8(struct M64ScriptState *state) { + u8 *midiArg = state->pc++; + return *midiArg; +} + +s16 m64_read_s16(struct M64ScriptState *state) { + s16 ret = *(state->pc++) << 8; + ret = *(state->pc++) | ret; + return ret; +} + +u16 m64_read_compressed_u16(struct M64ScriptState *state) { + u16 ret = *(state->pc++); + if (ret & 0x80) { + ret = (ret << 8) & 0x7f00; + ret = *(state->pc++) | ret; + } + return ret; +} + +// US/JP version of seq_channel_layer_process_script with macros to simulate +// inlining by copt. This version is basically identical to EU. + +#define COPT 0 +#if COPT +#define M64_READ_U8(state, dst) \ + dst = m64_read_u8(state); +#else +#define M64_READ_U8(state, dst) \ +{ \ + u8 * _ptr_pc; \ + u8 _pc; \ + _ptr_pc = (*state).pc; \ + ((*state).pc)++; \ + _pc = *_ptr_pc; \ + dst = _pc; \ +} +#endif + + +#if COPT +#define M64_READ_S16(state, dst) \ + dst = m64_read_s16(state); +#else +#define M64_READ_S16(state, dst) \ +{ \ + s16 _ret; \ + _ret = *(*state).pc << 8; \ + ((*state).pc)++; \ + _ret = *(*state).pc | _ret; \ + ((*state).pc)++; \ + dst = _ret; \ +} +#endif +#if COPT +#define M64_READ_COMPRESSED_U16(state, dst) \ + dst = m64_read_compressed_u16(state); +#else +#define M64_READ_COMPRESSED_U16(state, dst) \ +{ \ + u16 ret = *(state->pc++); \ + if (ret & 0x80) { \ + ret = (ret << 8) & 0x7f00; \ + ret = *(state->pc++) | ret; \ + } \ + dst = ret; \ +} +#endif + +#if COPT +#define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ + dst = get_instrument(seqChannel, instId, _instOut, _adsr); +#else +#define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ +{ \ +struct AdsrSettings *adsr = _adsr; \ +struct Instrument **instOut = _instOut;\ + u8 _instId = instId; \ + struct Instrument *inst; \ + UNUSED u32 pad; \ + /* copt inlines instId here */ \ + if (instId >= gCtlEntries[(*seqChannel).bankId].numInstruments) { \ + _instId = gCtlEntries[(*seqChannel).bankId].numInstruments; \ + if (_instId == 0) { \ + dst = 0; \ + goto ret ## l; \ + } \ + _instId--; \ + } \ + inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \ + if (inst == NULL) { \ + while (_instId != 0xff) { \ + inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \ + if (inst != NULL) { \ + goto gi ## l; \ + } \ + _instId--; \ + } \ + gi ## l:; \ + } \ + if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst \ + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start \ + + gBankLoadedPool.persistent.pool.size)) \ + || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst \ + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start \ + + gBankLoadedPool.temporary.pool.size))) { \ + (*adsr).envelope = (*inst).envelope; \ + (*adsr).releaseRate = (*inst).releaseRate; \ + *instOut = inst; \ + _instId++; \ + goto ret ## l; \ + } \ + gAudioErrorFlags = _instId + 0x20000; \ + *instOut = NULL; \ + ret ## l: ; \ +} +#endif + +void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { + struct SequencePlayer *seqPlayer; // sp5C, t4 + struct SequenceChannel *seqChannel; // sp58, t5 + struct M64ScriptState *state; + struct Portamento *portamento; + struct AudioBankSound *sound; + struct Instrument *instrument; + struct Drum *drum; + s32 temp_a0_5; + u8 sameSound; + u8 cmd; // a0 sp3E + u8 cmdSemitone; // sp3D, t0 + u16 sp3A; // t2, a0, a1 + f32 tuning; // f0 + s32 vel; // sp30, t3 + s32 usedSemitone; // a1 + f32 freqScale; // sp28, f0 + f32 sp24; + f32 temp_f12; + f32 temp_f2; + +//! Copt: manually inline these functions in the scope of this routine +#ifdef __sgi +#pragma inline routine(m64_read_u8) +#pragma inline routine(m64_read_compressed_u16) +#pragma inline routine(m64_read_s16) +#pragma inline routine(get_instrument) +#endif + + sameSound = TRUE; + if ((*layer).enabled == FALSE) { + return; + } + + if ((*layer).delay > 1) { + (*layer).delay--; + if (!layer->stopSomething && layer->delay <= layer->duration) { + seq_channel_layer_note_decay(layer); + layer->stopSomething = TRUE; + } + return; + } + + if (!layer->continuousNotes) { + seq_channel_layer_note_decay(layer); + } + + if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 || + PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) { + layer->portamento.mode = 0; + } + + seqChannel = (*layer).seqChannel; + seqPlayer = (*seqChannel).seqPlayer; + for (;;) { + state = &layer->scriptState; + //M64_READ_U8(state, cmd); + { + u8 *_ptr_pc; + _ptr_pc = (*state).pc++; + cmd = *_ptr_pc; + } + + if (cmd <= 0xc0) { + break; + } + + switch (cmd) { + case 0xff: // layer_end; function return or end of script + if (state->depth == 0) { + // N.B. this function call is *not* inlined even though it's + // within the same file, unlike in the rest of this function. + seq_channel_layer_disable(layer); + return; + } + state->depth--, state->pc = state->stack[state->depth]; + break; + + case 0xfc: // layer_call + M64_READ_S16(state, sp3A); + state->depth++, state->stack[state->depth - 1] = state->pc; + state->pc = seqPlayer->seqData + sp3A; + break; + + case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) + M64_READ_U8(state, state->remLoopIters[state->depth]); + state->depth++, state->stack[state->depth - 1] = state->pc; + break; + + case 0xf7: // layer_loopend + if (--state->remLoopIters[state->depth - 1] != 0) { + state->pc = state->stack[state->depth - 1]; + } else { + state->depth--; + } + break; + + case 0xfb: // layer_jump + M64_READ_S16(state, sp3A); + state->pc = seqPlayer->seqData + sp3A; + break; + + case 0xc1: // layer_setshortnotevelocity + case 0xca: // layer_setpan + temp_a0_5 = *(state->pc++); + if (cmd == 0xc1) { + layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5); + } else { + layer->pan = (f32) temp_a0_5 / JP_DOUBLE(128.0); + } + break; + + case 0xc2: // layer_transpose; set transposition in semitones + case 0xc9: // layer_setshortnoteduration + temp_a0_5 = *(state->pc++); + if (cmd == 0xc9) { + layer->noteDuration = temp_a0_5; + } else { + layer->transposition = temp_a0_5; + } + break; + + case 0xc4: // layer_somethingon + case 0xc5: // layer_somethingoff + //! copt needs a ternary: + //layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE; + { + u8 setting; + if (cmd == 0xc4) { + setting = TRUE; + } else { + setting = FALSE; + } + layer->continuousNotes = setting; + seq_channel_layer_note_decay(layer); + } + break; + + case 0xc3: // layer_setshortnotedefaultplaypercentage + M64_READ_COMPRESSED_U16(state, sp3A); + layer->shortNoteDefaultPlayPercentage = sp3A; + break; + + case 0xc6: // layer_setinstr + M64_READ_U8(state, cmdSemitone); + + if (cmdSemitone < 127) { + GET_INSTRUMENT(seqChannel, cmdSemitone, &(*layer).instrument, &(*layer).adsr, cmdSemitone, 1); + } + break; + + case 0xc7: // layer_portamento + M64_READ_U8(state, (*layer).portamento.mode); + M64_READ_U8(state, cmdSemitone); + + cmdSemitone = cmdSemitone + (*seqChannel).transposition; + cmdSemitone += (*layer).transposition; + cmdSemitone += (*seqPlayer).transposition; + + if (cmdSemitone >= 0x80) { + cmdSemitone = 0; + } + layer->portamentoTargetNote = cmdSemitone; + + // If special, the next param is u8 instead of var + if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) { + layer->portamentoTime = *((state)->pc++); + break; + } + + M64_READ_COMPRESSED_U16(state, sp3A); + layer->portamentoTime = sp3A; + break; + + case 0xc8: // layer_disableportamento + layer->portamento.mode = 0; + break; + + default: + switch (cmd & 0xf0) { + case 0xd0: // layer_setshortnotevelocityfromtable + sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xf]; + (*layer).velocitySquare = (f32)(sp3A * sp3A); + break; + case 0xe0: // layer_setshortnotedurationfromtable + (*layer).noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf]; + break; + } + } + } + + if (cmd == 0xc0) { // layer_delay + M64_READ_COMPRESSED_U16(state, layer->delay); + layer->stopSomething = TRUE; + } else { + layer->stopSomething = FALSE; + + if (seqChannel->largeNotes == TRUE) { + switch (cmd & 0xc0) { + case 0x00: // layer_note0 (play percentage, velocity, duration) + M64_READ_COMPRESSED_U16(state, sp3A); + vel = *((*state).pc++); + layer->noteDuration = *((*state).pc++); + layer->playPercentage = sp3A; + goto l1090; + + case 0x40: // layer_note1 (play percentage, velocity) + M64_READ_COMPRESSED_U16(state, sp3A); + vel = *((*state).pc++); + layer->noteDuration = 0; + layer->playPercentage = sp3A; + goto l1090; + + case 0x80: // layer_note2 (velocity, duration; uses last play percentage) + sp3A = layer->playPercentage; + vel = *((*state).pc++); + layer->noteDuration = *((*state).pc++); + goto l1090; + } +l1090: + cmdSemitone = cmd - (cmd & 0xc0); + layer->velocitySquare = vel * vel; + } else { + switch (cmd & 0xc0) { + case 0x00: // play note, type 0 (play percentage) + M64_READ_COMPRESSED_U16(state, sp3A); + layer->playPercentage = sp3A; + goto l1138; + + case 0x40: // play note, type 1 (uses default play percentage) + sp3A = layer->shortNoteDefaultPlayPercentage; + goto l1138; + + case 0x80: // play note, type 2 (uses last play percentage) + sp3A = layer->playPercentage; + goto l1138; + } +l1138: + + cmdSemitone = cmd - (cmd & 0xc0); + } + + layer->delay = sp3A; + layer->duration = layer->noteDuration * sp3A / 256; + if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0) + || seqChannel->stopSomething2 + || !seqChannel->hasInstrument + ) { + layer->stopSomething = TRUE; + } else { + if (seqChannel->instOrWave == 0) { // drum + cmdSemitone += (*seqChannel).transposition + (*layer).transposition; + if (cmdSemitone >= gCtlEntries[seqChannel->bankId].numDrums) { + cmdSemitone = gCtlEntries[seqChannel->bankId].numDrums; + if (cmdSemitone == 0) { + // this goto looks a bit like a function return... + layer->stopSomething = TRUE; + goto skip; + } + + cmdSemitone--; + } + + drum = gCtlEntries[seqChannel->bankId].drums[cmdSemitone]; + if (drum == NULL) { + layer->stopSomething = TRUE; + } else { + layer->adsr.envelope = drum->envelope; + layer->adsr.releaseRate = drum->releaseRate; + layer->pan = FLOAT_CAST(drum->pan) / JP_DOUBLE(128.0); + layer->sound = &drum->sound; + layer->freqScale = layer->sound->tuning; + } + + skip:; + } else { // instrument + cmdSemitone += (*seqPlayer).transposition + (*seqChannel).transposition + (*layer).transposition; + if (cmdSemitone >= 0x80) { + layer->stopSomething = TRUE; + } else { + instrument = layer->instrument; + if (instrument == NULL) { + instrument = seqChannel->instrument; + } + + if (layer->portamento.mode != 0) { + //! copt needs a ternary: + //usedSemitone = (layer->portamentoTargetNote < cmdSemitone) ? cmdSemitone : layer->portamentoTargetNote; + if (layer->portamentoTargetNote < cmdSemitone) { + usedSemitone = cmdSemitone; + } else { + usedSemitone = layer->portamentoTargetNote; + } + + if (instrument != NULL) { + sound = (u8) usedSemitone < instrument->normalRangeLo ? &instrument->lowNotesSound + : (u8) usedSemitone <= instrument->normalRangeHi ? + &instrument->normalNotesSound : &instrument->highNotesSound; + + sameSound = (sound == (*layer).sound); + layer->sound = sound; + tuning = (*sound).tuning; + } else { + layer->sound = NULL; + tuning = 1.0f; + } + + temp_f2 = gNoteFrequencies[cmdSemitone] * tuning; + temp_f12 = gNoteFrequencies[layer->portamentoTargetNote] * tuning; + + portamento = &layer->portamento; + switch (PORTAMENTO_MODE(layer->portamento)) { + case PORTAMENTO_MODE_1: + case PORTAMENTO_MODE_3: + case PORTAMENTO_MODE_5: + sp24 = temp_f2; + freqScale = temp_f12; + goto l13cc; + + case PORTAMENTO_MODE_2: + case PORTAMENTO_MODE_4: + freqScale = temp_f2; + sp24 = temp_f12; + goto l13cc; + } +l13cc: + portamento->extent = sp24 / freqScale - JP_DOUBLE(1.0); + if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) { + portamento->speed = JP_DOUBLE(32512.0) * FLOAT_CAST((*seqPlayer).tempo) + / ((f32)(*layer).delay * (f32) gTempoInternalToExternal + * FLOAT_CAST((*layer).portamentoTime)); + } else { + portamento->speed = JP_DOUBLE(127.0) / FLOAT_CAST((*layer).portamentoTime); + } + portamento->cur = 0.0f; + layer->freqScale = freqScale; + if (PORTAMENTO_MODE((*layer).portamento) == PORTAMENTO_MODE_5) { + layer->portamentoTargetNote = cmdSemitone; + } + } else if (instrument != NULL) { + sound = cmdSemitone < instrument->normalRangeLo ? + &instrument->lowNotesSound : cmdSemitone <= instrument->normalRangeHi ? + &instrument->normalNotesSound : &instrument->highNotesSound; + + sameSound = (sound == (*layer).sound); + layer->sound = sound; + layer->freqScale = gNoteFrequencies[cmdSemitone] * (*sound).tuning; + } else { + layer->sound = NULL; + layer->freqScale = gNoteFrequencies[cmdSemitone]; + } + } + } + layer->delayUnused = layer->delay; + } + } + + if (layer->stopSomething == TRUE) { + if (layer->note != NULL || layer->continuousNotes) { + seq_channel_layer_note_decay(layer); + } + return; + } + + cmdSemitone = FALSE; + if (!layer->continuousNotes) { + cmdSemitone = TRUE; + } else if (layer->note == NULL || layer->status == SOUND_LOAD_STATUS_NOT_LOADED) { + cmdSemitone = TRUE; + } else if (sameSound == FALSE) { + seq_channel_layer_note_decay(layer); + cmdSemitone = TRUE; + } else if (layer->sound == NULL) { + init_synthetic_wave(layer->note, layer); + } + + if (cmdSemitone != FALSE) { + (*layer).note = alloc_note(layer); + } + + if (layer->note != NULL && layer->note->parentLayer == layer) { + note_vibrato_init(layer->note); + } +} + +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) { + struct Instrument *inst; + UNUSED u32 pad; + + if (instId >= gCtlEntries[seqChannel->bankId].numInstruments) { + instId = gCtlEntries[seqChannel->bankId].numInstruments; + if (instId == 0) { + return 0; + } + instId--; + } + + inst = gCtlEntries[seqChannel->bankId].instruments[instId]; + if (inst == NULL) { + struct SequenceChannel seqChannelCpy = *seqChannel; + + while (instId != 0xff) { + inst = gCtlEntries[seqChannelCpy.bankId].instruments[instId]; + if (inst != NULL) { + break; + } + instId--; + } + } + + if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start + + gBankLoadedPool.persistent.pool.size)) + || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start + + gBankLoadedPool.temporary.pool.size))) { + adsr->envelope = inst->envelope; + adsr->releaseRate = inst->releaseRate; + *instOut = inst; + instId++; + return instId; + } + + gAudioErrorFlags = instId + 0x20000; + *instOut = NULL; + return 0; +} + +void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { + if (instId >= 0x80) { + seqChannel->instOrWave = instId; + seqChannel->instrument = NULL; + } else if (instId == 0x7f) { + seqChannel->instOrWave = 0; + seqChannel->instrument = (struct Instrument *) 1; + } else { + seqChannel->instOrWave = + get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr); + if (seqChannel->instOrWave == 0) + { + seqChannel->hasInstrument = FALSE; + return; + } + } + seqChannel->hasInstrument = TRUE; +} + +void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume) { + seqChannel->volume = FLOAT_CAST(volume) / JP_DOUBLE(127.0); +} + +void sequence_channel_process_script(struct SequenceChannel *seqChannel) { + struct M64ScriptState *state; + struct SequencePlayer *seqPlayer; + u8 cmd; + s8 temp; + u8 loBits; + u16 sp5A; + s32 sp38; + s8 value; + s32 i; + u8 *seqData; + + if (!seqChannel->enabled) { + return; + } + + if (seqChannel->stopScript) { + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != NULL) { + seq_channel_layer_process_script(seqChannel->layers[i]); + } + } + return; + } + + seqPlayer = seqChannel->seqPlayer; + if (seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT) != 0) { + return; + } + + if (seqChannel->delay != 0) { + seqChannel->delay--; + } + + state = &seqChannel->scriptState; + if (seqChannel->delay == 0) { + for (;;) { + cmd = m64_read_u8(state); + if (cmd == 0xff) { // chan_end + if (state->depth == 0) { + sequence_channel_disable(seqChannel); + break; + } + state->depth--, state->pc = state->stack[state->depth]; + } + if (cmd == 0xfe) { // chan_delay1 + break; + } + if (cmd == 0xfd) { // chan_delay + seqChannel->delay = m64_read_compressed_u16(state); + break; + } + if (cmd == 0xf3) { // chan_hang + seqChannel->stopScript = TRUE; + break; + } + + if (cmd > 0xc0) + { + switch (cmd) { + case 0xff: // chan_end + break; + + case 0xfc: // chan_call + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Audio:Track :Call Macro Level Over Error!\n"); + } + sp5A = m64_read_s16(state); + state->depth++, state->stack[state->depth - 1] = state->pc; + state->pc = seqPlayer->seqData + sp5A; + break; + + case 0xf8: // chan_loop; loop start, N iterations (or 256 if N = 0) + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Audio:Track :Loops Macro Level Over Error!\n"); + } + state->remLoopIters[state->depth] = m64_read_u8(state); + state->depth++, state->stack[state->depth - 1] = state->pc; + break; + + case 0xf7: // chan_loopend + state->remLoopIters[state->depth - 1]--; + if (state->remLoopIters[state->depth - 1] != 0) { + state->pc = state->stack[state->depth - 1]; + } else { + state->depth--; + } + break; + + case 0xf6: // chan_break; break loop, if combined with jump + state->depth--; + break; + + case 0xfb: // chan_jump + case 0xfa: // chan_beqz + case 0xf9: // chan_bltz + case 0xf5: // chan_bgez + sp5A = m64_read_s16(state); + if (cmd == 0xfa && value != 0) { + break; + } + if (cmd == 0xf9 && value >= 0) { + break; + } + if (cmd == 0xf5 && value < 0) { + break; + } + state->pc = seqPlayer->seqData + sp5A; + break; + + case 0xf2: // chan_reservenotes + note_pool_clear(&seqChannel->notePool); + note_pool_fill(&seqChannel->notePool, m64_read_u8(state)); + break; + + case 0xf1: // chan_unreservenotes + note_pool_clear(&seqChannel->notePool); + break; + + case 0xc2: // chan_setdyntable + sp5A = m64_read_s16(state); + seqChannel->dynTable = (void *) (seqPlayer->seqData + sp5A); + break; + + case 0xc5: // chan_dynsetdyntable + if (value != -1) { + sp5A = (u16)((((*seqChannel->dynTable)[value])[0] << 8) + (((*seqChannel->dynTable)[value])[1])); + seqChannel->dynTable = (void *) (seqPlayer->seqData + sp5A); + } + break; + + case 0xc1: // chan_setinstr ("set program"?) + set_instrument(seqChannel, m64_read_u8(state)); + break; + + case 0xc3: // chan_largenotesoff + seqChannel->largeNotes = FALSE; + break; + + case 0xc4: // chan_largenoteson + seqChannel->largeNotes = TRUE; + break; + + case 0xdf: // chan_setvol + sequence_channel_set_volume(seqChannel, m64_read_u8(state)); + break; + + case 0xe0: // chan_setvolscale + seqChannel->volumeScale = FLOAT_CAST(m64_read_u8(state)) / JP_DOUBLE(128.0); + break; + + case 0xde: // chan_freqscale; pitch bend using raw frequency multiplier N/2^15 (N is u16) + sp5A = m64_read_s16(state); + seqChannel->freqScale = FLOAT_CAST(sp5A) / JP_DOUBLE(32768.0); + break; + + case 0xd3: // chan_pitchbend; pitch bend by <= 1 octave in either direction (-127..127) + // (m64_read_u8(state) is really s8 here) + cmd = m64_read_u8(state) + 127; + seqChannel->freqScale = gPitchBendFrequencyScale[cmd]; + break; + + case 0xdd: // chan_setpan + seqChannel->pan = FLOAT_CAST(m64_read_u8(state)) / JP_DOUBLE(128.0); + break; + + case 0xdc: // chan_setpanmix; set proportion of pan to come from channel (0..128) + seqChannel->panChannelWeight = FLOAT_CAST(m64_read_u8(state)) / JP_DOUBLE(128.0); + break; + + case 0xdb: // chan_transpose; set transposition in semitones + temp = *state->pc++; + seqChannel->transposition = temp; + break; + + case 0xda: // chan_setenvelope + sp5A = m64_read_s16(state); + seqChannel->adsr.envelope = (struct AdsrEnvelope *) (seqPlayer->seqData + sp5A); + break; + + case 0xd9: // chan_setdecayrelease + seqChannel->adsr.releaseRate = m64_read_u8(state); + break; + + case 0xd8: // chan_setvibratoextent + seqChannel->vibratoExtentTarget = m64_read_u8(state) * 8; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoExtentChangeDelay = 0; + break; + + case 0xd7: // chan_setvibratorate + seqChannel->vibratoRateStart = seqChannel->vibratoRateTarget = + m64_read_u8(state) * 32; + seqChannel->vibratoRateChangeDelay = 0; + break; + + case 0xe2: // chan_setvibratoextentlinear + seqChannel->vibratoExtentStart = m64_read_u8(state) * 8; + seqChannel->vibratoExtentTarget = m64_read_u8(state) * 8; + seqChannel->vibratoExtentChangeDelay = m64_read_u8(state) * 16; + break; + + case 0xe1: // chan_setvibratoratelinear + seqChannel->vibratoRateStart = m64_read_u8(state) * 32; + seqChannel->vibratoRateTarget = m64_read_u8(state) * 32; + seqChannel->vibratoRateChangeDelay = m64_read_u8(state) * 16; + break; + + case 0xe3: // chan_setvibratodelay + seqChannel->vibratoDelay = m64_read_u8(state) * 16; + break; + + case 0xd6: // chan_setupdatesperframe_unimplemented + cmd = m64_read_u8(state); + if (cmd == 0) { + cmd = gAudioUpdatesPerFrame; + } + seqChannel->updatesPerFrameUnused = cmd; + break; + + case 0xd4: // chan_setreverb + seqChannel->reverbVol = m64_read_u8(state); + break; + + case 0xc6: // chan_setbank; switch bank within set + cmd = m64_read_u8(state); + // Switch to the temp's (0-indexed) bank in this sequence's + // bank set. Note that in the binary format (not in the JSON!) + // the banks are listed backwards, so we counts from the back. + // (gAlBankSets[offset] is number of banks) + sp5A = ((u16 *) gAlBankSets)[seqPlayer->seqId]; + loBits = *(sp5A + gAlBankSets); + cmd = gAlBankSets[sp5A + loBits - cmd]; + if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL) + { + seqChannel->bankId = cmd; + } else { + eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", cmd); + } + break; + + case 0xc7: // chan_writeseq; write to sequence data (!) + { + u8 *seqData; + cmd = m64_read_u8(state); + sp5A = m64_read_s16(state); + seqData = seqPlayer->seqData + sp5A; + *seqData = (u8)value + cmd; + } + break; + + case 0xc8: // chan_subtract + case 0xc9: // chan_bitand + case 0xcc: // chan_setval + temp = m64_read_u8(state); + if (cmd == 0xc8) { + value -= temp; + } else if (cmd == 0xcc) { + value = temp; + } else { + value &= temp; + } + break; + + case 0xca: // chan_setmutebhv + seqChannel->muteBehavior = m64_read_u8(state); + break; + + case 0xcb: // chan_readseq + sp38 = (u16)m64_read_s16(state) + value; + value = seqPlayer->seqData[sp38]; + break; + + case 0xd0: // chan_stereoheadseteffects + seqChannel->stereoHeadsetEffects = m64_read_u8(state); + break; + + case 0xd1: // chan_setnoteallocationpolicy + seqChannel->noteAllocPolicy = m64_read_u8(state); + break; + + case 0xd2: // chan_setsustain + seqChannel->adsr.sustain = m64_read_u8(state) << 8; + break; + case 0xe4: // chan_dyncall + if (value != -1) { + seqData = (*seqChannel->dynTable)[value]; + state->depth++, state->stack[state->depth - 1] = state->pc; + sp5A = ((seqData[0] << 8) + seqData[1]); + state->pc = seqPlayer->seqData + sp5A; + } + break; + } + } else { + loBits = cmd & 0xf; + + switch (cmd & 0xf0) { + case 0x00: // chan_testlayerfinished + if (seqChannel->layers[loBits] != NULL) { + value = seqChannel->layers[loBits]->finished; + } + break; + + // sh: 0x70 + case 0x70: // chan_iowriteval; write data back to audio lib + seqChannel->soundScriptIO[loBits] = value; + break; + + case 0x80: // chan_ioreadval; read data from audio lib + value = seqChannel->soundScriptIO[loBits]; + if (loBits < 4) { + seqChannel->soundScriptIO[loBits] = -1; + } + break; + + // sh: 0x50 + case 0x50: // chan_ioreadvalsub; subtract with read data from audio lib + value -= seqChannel->soundScriptIO[loBits]; + break; + + case 0x90: // chan_setlayer + sp5A = m64_read_s16(state); + if (seq_channel_set_layer(seqChannel, loBits) == 0) { + seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; + } + break; + + case 0xa0: // chan_freelayer + seq_channel_layer_free(seqChannel, loBits); + break; + + case 0xb0: // chan_dynsetlayer + if (value != -1 && seq_channel_set_layer(seqChannel, loBits) != -1) { + seqData = (*seqChannel->dynTable)[value]; + sp5A = ((seqData[0] << 8) + seqData[1]); + seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; + } + break; + + case 0x60: // chan_setnotepriority (arg must be >= 2) + seqChannel->notePriority = loBits; + break; + + case 0x10: // chan_startchannel + sp5A = m64_read_s16(state); + sequence_channel_enable(seqPlayer, loBits, seqPlayer->seqData + sp5A); + break; + + case 0x20: // chan_disablechannel + sequence_channel_disable(seqPlayer->channels[loBits]); + break; + + case 0x30: // chan_iowriteval2; write data back to audio lib for another channel + cmd = m64_read_u8(state); + seqPlayer->channels[loBits]->soundScriptIO[cmd] = value; + break; + + case 0x40: // chan_ioreadval2; read data from audio lib from another channel + cmd = m64_read_u8(state); + value = seqPlayer->channels[loBits]->soundScriptIO[cmd]; + break; + } + } + } + } + + for (i = 0; i < LAYERS_MAX; i++) { + if (seqChannel->layers[i] != 0) { + seq_channel_layer_process_script(seqChannel->layers[i]); + } + } +} + +void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { + u8 cmd; + u8 loBits; + u8 temp; + s32 value; + s32 i; + u16 u16v; + u8 *seqData; + struct M64ScriptState *state; + + if (seqPlayer->enabled == FALSE) { + return; + } + + if (seqPlayer->bankDmaInProgress == TRUE) { + if (seqPlayer->bankDmaMesg == NULL) { + return; + } + if (seqPlayer->bankDmaRemaining == 0) { + seqPlayer->bankDmaInProgress = FALSE; + patch_audio_bank(seqPlayer->loadingBank, gAlTbl->seqArray[seqPlayer->loadingBankId].offset, + seqPlayer->loadingBankNumInstruments, seqPlayer->loadingBankNumDrums); + gCtlEntries[seqPlayer->loadingBankId].numInstruments = seqPlayer->loadingBankNumInstruments; + gCtlEntries[seqPlayer->loadingBankId].numDrums = seqPlayer->loadingBankNumDrums; + gCtlEntries[seqPlayer->loadingBankId].instruments = seqPlayer->loadingBank->instruments; + gCtlEntries[seqPlayer->loadingBankId].drums = seqPlayer->loadingBank->drums; + gBankLoadStatus[seqPlayer->loadingBankId] = SOUND_LOAD_STATUS_COMPLETE; + } else { + osCreateMesgQueue(&seqPlayer->bankDmaMesgQueue, &seqPlayer->bankDmaMesg, 1); + seqPlayer->bankDmaMesg = NULL; + audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, + &seqPlayer->bankDmaRemaining, &seqPlayer->bankDmaMesgQueue, + &seqPlayer->bankDmaIoMesg); + } + return; + } + + if (seqPlayer->seqDmaInProgress == TRUE) { + if (seqPlayer->seqDmaMesg == NULL) { + return; + } + seqPlayer->seqDmaInProgress = FALSE; + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; + } + + // If discarded, bail out. + if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) == FALSE + || ( + IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) == FALSE)) { + eu_stubbed_printf_1("Disappear Sequence or Bank %d\n", seqPlayer->seqId); + sequence_player_disable(seqPlayer); + return; + } + + // Remove possible SOUND_LOAD_STATUS_DISCARDABLE marks. + gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; + + gBankLoadStatus[seqPlayer->defaultBank[0]] = SOUND_LOAD_STATUS_COMPLETE; + + if (seqPlayer->muted && (seqPlayer->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT) != 0) { + return; + } + + // Check if we surpass the number of ticks needed for a tatum, else stop. + seqPlayer->tempoAcc += seqPlayer->tempo; + if (seqPlayer->tempoAcc < gTempoInternalToExternal) { + return; + } + seqPlayer->tempoAcc -= (u16) gTempoInternalToExternal; + + state = &seqPlayer->scriptState; + if (seqPlayer->delay > 1) { +#ifndef AVOID_UB + if (temp) { + } +#endif + seqPlayer->delay--; + } else { + for (;;) { + cmd = m64_read_u8(state); + if (cmd == 0xff) { // seq_end + if (state->depth == 0) { + sequence_player_disable(seqPlayer); + break; + } + state->depth--, state->pc = state->stack[state->depth]; + } + + if (cmd == 0xfd) { // seq_delay + seqPlayer->delay = m64_read_compressed_u16(state); + break; + } + + if (cmd == 0xfe) { // seq_delay1 + seqPlayer->delay = 1; + break; + } + + if (cmd >= 0xc0) { + switch (cmd) { + case 0xff: // seq_end + break; + + case 0xfc: // seq_call + u16v = m64_read_s16(state); + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Macro Level Over Error!\n"); + } + state->depth++, state->stack[state->depth - 1] = state->pc; + state->pc = seqPlayer->seqData + u16v; + break; + + case 0xf8: // seq_loop; loop start, N iterations (or 256 if N = 0) + if (0 && state->depth >= 4) { + eu_stubbed_printf_0("Macro Level Over Error!\n"); + } + state->remLoopIters[state->depth] = m64_read_u8(state); + state->depth++, state->stack[state->depth - 1] = state->pc; + break; + + case 0xf7: // seq_loopend + state->remLoopIters[state->depth - 1]--; + if (state->remLoopIters[state->depth - 1] != 0) { + state->pc = state->stack[state->depth - 1]; + } else { + state->depth--; + } + break; + + case 0xfb: // seq_jump + case 0xfa: // seq_beqz; jump if == 0 + case 0xf9: // seq_bltz; jump if < 0 + case 0xf5: // seq_bgez; jump if >= 0 + u16v = m64_read_s16(state); + if (cmd == 0xfa && value != 0) { + break; + } + if (cmd == 0xf9 && value >= 0) { + break; + } + if (cmd == 0xf5 && value < 0) { + break; + } + state->pc = seqPlayer->seqData + u16v; + break; + + case 0xf2: // seq_reservenotes + note_pool_clear(&seqPlayer->notePool); + note_pool_fill(&seqPlayer->notePool, m64_read_u8(state)); + break; + + case 0xf1: // seq_unreservenotes + note_pool_clear(&seqPlayer->notePool); + break; + + case 0xdf: // seq_transpose; set transposition in semitones + seqPlayer->transposition = 0; + // fallthrough + + case 0xde: // seq_transposerel; add transposition + seqPlayer->transposition += (s8) m64_read_u8(state); + break; + + case 0xdd: // seq_settempo (bpm) + case 0xdc: // seq_addtempo (bpm) + temp = m64_read_u8(state); + if (cmd == 0xdd) { + seqPlayer->tempo = temp * TEMPO_SCALE; + } else { + seqPlayer->tempo += (s8) temp * TEMPO_SCALE; + } + + if (seqPlayer->tempo > gTempoInternalToExternal) { + seqPlayer->tempo = gTempoInternalToExternal; + } + + //if (cmd) {} + + if ((s16) seqPlayer->tempo <= 0) { + seqPlayer->tempo = 1; + } + break; + + case 0xdb: // seq_setvol + cmd = m64_read_u8(state); + switch (seqPlayer->state) { + case SEQUENCE_PLAYER_STATE_2: + if (seqPlayer->fadeRemainingFrames != 0) { + f32 targetVolume = FLOAT_CAST(cmd) / JP_DOUBLE(127.0); + seqPlayer->fadeVelocity = (targetVolume - seqPlayer->fadeVolume) + / FLOAT_CAST(seqPlayer->fadeRemainingFrames); + break; + } + // fallthrough + case SEQUENCE_PLAYER_STATE_0: + seqPlayer->fadeVolume = FLOAT_CAST(cmd) / JP_DOUBLE(127.0); + break; + case SEQUENCE_PLAYER_STATE_FADE_OUT: + case SEQUENCE_PLAYER_STATE_4: + seqPlayer->volume = FLOAT_CAST(cmd) / JP_DOUBLE(127.0); + break; + } + break; + + case 0xda: // seq_changevol + temp = m64_read_u8(state); + seqPlayer->fadeVolume = + seqPlayer->fadeVolume + (f32)(s8) temp / JP_DOUBLE(127.0); + break; + + case 0xd7: // seq_initchannels + u16v = m64_read_s16(state); + sequence_player_init_channels(seqPlayer, u16v); + break; + + case 0xd6: // seq_disablechannels + u16v = m64_read_s16(state); + sequence_player_disable_channels(seqPlayer, u16v); + break; + + case 0xd5: // seq_setmutescale + temp = m64_read_u8(state); + seqPlayer->muteVolumeScale = (f32)(s8) temp / JP_DOUBLE(127.0); + break; + + case 0xd4: // seq_mute + seqPlayer->muted = TRUE; + break; + + case 0xd3: // seq_setmutebhv + seqPlayer->muteBehavior = m64_read_u8(state); + break; + + case 0xd2: // seq_setshortnotevelocitytable + case 0xd1: // seq_setshortnotedurationtable + u16v = m64_read_s16(state); + seqData = seqPlayer->seqData + u16v; + if (cmd == 0xd2) { + seqPlayer->shortNoteVelocityTable = seqData; + } else { + seqPlayer->shortNoteDurationTable = seqData; + } + break; + + case 0xd0: // seq_setnoteallocationpolicy + seqPlayer->noteAllocPolicy = m64_read_u8(state); + break; + + case 0xcc: // seq_setval + value = m64_read_u8(state); + break; + + case 0xc9: // seq_bitand + value = m64_read_u8(state) & value; + break; + + case 0xc8: // seq_subtract + value = value - m64_read_u8(state); + break; + + default: + eu_stubbed_printf_1("Group:Undefine upper C0h command (%x)\n", cmd); + break; + } + } else { + loBits = cmd & 0xf; + switch (cmd & 0xf0) { + case 0x00: // seq_testchdisabled + if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[loBits]) == TRUE) { + value = seqPlayer->channels[loBits]->finished; + } + break; + case 0x10: + break; + case 0x20: + break; + case 0x40: + break; + case 0x50: // seq_subvariation + value -= seqPlayer->seqVariation; + break; + case 0x60: + break; + case 0x70: // seq_setvariation + seqPlayer->seqVariation = value; + break; + case 0x80: // seq_getvariation + value = seqPlayer->seqVariation; + break; + case 0x90: // seq_startchannel + u16v = m64_read_s16(state); + sequence_channel_enable(seqPlayer, loBits, seqPlayer->seqData + u16v); + break; + case 0xa0: + break; + case 0xd8: // (this makes no sense) + break; + case 0xd9: + break; + + default: + eu_stubbed_printf_0("Group:Undefined Command\n"); + break; + } + } + } + } + + for (i = 0; i < CHANNELS_MAX; i++) { + if (seqPlayer->channels[i] != &gSequenceChannelNone) { + sequence_channel_process_script(seqPlayer->channels[i]); + } + } +} + +// This runs 240 times per second. +void process_sequences(UNUSED s32 iterationsRemaining) { + s32 i; + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + if (gSequencePlayers[i].enabled == TRUE) { + sequence_player_process_sequence(gSequencePlayers + i); + sequence_player_process_sound(gSequencePlayers + i); + } + } + reclaim_notes(); + process_notes(); +} + +void init_sequence_player(u32 player) { + struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; + seqPlayer->muted = FALSE; + seqPlayer->delay = 0; + seqPlayer->state = SEQUENCE_PLAYER_STATE_0; + seqPlayer->fadeRemainingFrames = 0; + seqPlayer->tempoAcc = 0; + seqPlayer->tempo = 120 * TEMPO_SCALE; // 120 BPM + seqPlayer->transposition = 0; + seqPlayer->muteBehavior = MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_SOFTEN; + seqPlayer->noteAllocPolicy = 0; + seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; + seqPlayer->shortNoteDurationTable = gDefaultShortNoteDurationTable; + seqPlayer->fadeVolume = 1.0f; + seqPlayer->fadeVelocity = 0.0f; + seqPlayer->volume = 0.0f; + seqPlayer->muteVolumeScale = 0.5f; +} + +void init_sequence_players(void) { + // Initialization function, called from audio_init + s32 i, j; + + for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { + gSequenceChannels[i].seqPlayer = NULL; + gSequenceChannels[i].enabled = FALSE; + } + + for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { + // @bug Size of wrong array. Zeroes out second half of gSequenceChannels[0], + // all of gSequenceChannels[1..31], and part of gSequenceLayers[0]. + // However, this is only called at startup, so it's harmless. +#ifdef AVOID_UB +#define LAYERS_SIZE LAYERS_MAX +#else +#define LAYERS_SIZE ARRAY_COUNT(gSequenceLayers) +#endif + for (j = 0; j < LAYERS_SIZE; j++) { + gSequenceChannels[i].layers[j] = NULL; + } + } + + init_layer_freelist(); + + for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { + gSequenceLayers[i].seqChannel = NULL; + gSequenceLayers[i].enabled = FALSE; + } + + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + for (j = 0; j < CHANNELS_MAX; j++) { + gSequencePlayers[i].channels[j] = &gSequenceChannelNone; + } + + gSequencePlayers[i].seqVariation = -1; + gSequencePlayers[i].bankDmaInProgress = FALSE; + gSequencePlayers[i].seqDmaInProgress = FALSE; + init_note_lists(&gSequencePlayers[i].notePool); + init_sequence_player(i); + } +} + diff --git a/src/audio/us_jp/seqplayer.h b/src/audio/us_jp/seqplayer.h new file mode 100644 index 00000000..d2fc1344 --- /dev/null +++ b/src/audio/us_jp/seqplayer.h @@ -0,0 +1,18 @@ +#ifndef AUDIO_SEQPLAYER_H +#define AUDIO_SEQPLAYER_H + +#include + +#include "internal.h" +#include "playback.h" + +void seq_channel_layer_disable(struct SequenceChannelLayer *seqPlayer); +void sequence_channel_disable(struct SequenceChannel *seqPlayer); +void sequence_player_disable(struct SequencePlayer* seqPlayer); +void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item); +void *audio_list_pop_back(struct AudioListItem *list); +void process_sequences(s32 iterationsRemaining); +void init_sequence_player(u32 player); +void init_sequence_players(void); + +#endif // AUDIO_SEQPLAYER_H diff --git a/src/audio/us_jp/synthesis.c b/src/audio/us_jp/synthesis.c new file mode 100644 index 00000000..55f457b5 --- /dev/null +++ b/src/audio/us_jp/synthesis.c @@ -0,0 +1,879 @@ +#include + +#include "synthesis.h" +#include "heap.h" +#include "data.h" +#include "load.h" +#include "seqplayer.h" +#include "internal.h" +#include "../external.h" + + +#define DMEM_ADDR_TEMP 0x0 +#define DMEM_ADDR_RESAMPLED 0x20 +#define DMEM_ADDR_RESAMPLED2 0x160 +#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180 +#define DMEM_ADDR_NOTE_PAN_TEMP 0x200 +#define DMEM_ADDR_STEREO_STRONG_TEMP_DRY 0x200 +#define DMEM_ADDR_STEREO_STRONG_TEMP_WET 0x340 +#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x3f0 +#define DMEM_ADDR_LEFT_CH 0x4c0 +#define DMEM_ADDR_RIGHT_CH 0x600 +#define DMEM_ADDR_WET_LEFT_CH 0x740 +#define DMEM_ADDR_WET_RIGHT_CH 0x880 + +#define aSetLoadBufferPair(pkt, c, off) \ + aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_LEFT_CH, 0, DEFAULT_LEN_1CH - c); \ + aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \ + aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_RIGHT_CH, 0, DEFAULT_LEN_1CH - c); \ + aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off))) + +#define aSetSaveBufferPair(pkt, c, d, off) \ + aSetBuffer(pkt, 0, 0, c + DMEM_ADDR_WET_LEFT_CH, d); \ + aSaveBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \ + aSetBuffer(pkt, 0, 0, c + DMEM_ADDR_WET_RIGHT_CH, d); \ + aSaveBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off))); + +#define ALIGN(val, amnt) (((val) + (1 << amnt) - 1) & ~((1 << amnt) - 1)) + +struct VolumeChange { + u16 sourceLeft; + u16 sourceRight; + u16 targetLeft; + u16 targetRight; +}; + +u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); +u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd); +u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad); +u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags); +u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, + u32 flags); +u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, + s32 headsetPanSettings, struct VolumeChange *vol); +u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight); + +struct SynthesisReverb gSynthesisReverb; +u8 sAudioSynthesisPad[0x20]; + +void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { + struct ReverbRingBufferItem *item; + s32 srcPos; + s32 dstPos; + s32 nSamples; + s32 numSamplesAfterDownsampling; + s32 excessiveSamples; + if (gReverbDownsampleRate != 1) { + if (gSynthesisReverb.framesLeftToIgnore == 0) { + // Now that the RSP has finished, downsample the samples produced two frames ago by skipping + // samples. + item = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; + + // Touches both left and right since they are adjacent in memory + osInvalDCache(item->toDownsampleLeft, DEFAULT_LEN_2CH); + + for (srcPos = 0, dstPos = 0; dstPos < item->lengthA / 2; + srcPos += gReverbDownsampleRate, dstPos++) { + gSynthesisReverb.ringBuffer.left[dstPos + item->startPos] = + item->toDownsampleLeft[srcPos]; + gSynthesisReverb.ringBuffer.right[dstPos + item->startPos] = + item->toDownsampleRight[srcPos]; + } + for (dstPos = 0; dstPos < item->lengthB / 2; srcPos += gReverbDownsampleRate, dstPos++) { + gSynthesisReverb.ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos]; + gSynthesisReverb.ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos]; + } + } + } + item = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; + + numSamplesAfterDownsampling = chunkLen / gReverbDownsampleRate; + if (((numSamplesAfterDownsampling + gSynthesisReverb.nextRingBufferPos) - gSynthesisReverb.bufSizePerChannel) < 0) { + // There is space in the ring buffer before it wraps around + item->lengthA = numSamplesAfterDownsampling * 2; + item->lengthB = 0; + item->startPos = (s32) gSynthesisReverb.nextRingBufferPos; + gSynthesisReverb.nextRingBufferPos += numSamplesAfterDownsampling; + } else { + // Ring buffer wrapped around + excessiveSamples = + (numSamplesAfterDownsampling + gSynthesisReverb.nextRingBufferPos) - gSynthesisReverb.bufSizePerChannel; + nSamples = numSamplesAfterDownsampling - excessiveSamples; + item->lengthA = nSamples * 2; + item->lengthB = excessiveSamples * 2; + item->startPos = gSynthesisReverb.nextRingBufferPos; + gSynthesisReverb.nextRingBufferPos = excessiveSamples; + } + // These fields are never read later + item->numSamplesAfterDownsampling = numSamplesAfterDownsampling; + item->chunkLen = chunkLen; +} + +s32 get_volume_ramping(u16 sourceVol, u16 targetVol, s32 arg2) { + // This roughly computes 2^16 * (targetVol / sourceVol) ^ (8 / arg2), + // but with discretizations of targetVol, sourceVol and arg2. + f32 ret; + switch (arg2) { + default: + ret = gVolRampingLhs136[targetVol >> 8] * gVolRampingRhs136[sourceVol >> 8]; + break; + case 128: + ret = gVolRampingLhs128[targetVol >> 8] * gVolRampingRhs128[sourceVol >> 8]; + break; + case 136: + ret = gVolRampingLhs136[targetVol >> 8] * gVolRampingRhs136[sourceVol >> 8]; + break; + case 144: + ret = gVolRampingLhs144[targetVol >> 8] * gVolRampingRhs144[sourceVol >> 8]; + break; + } + return ret; +} + +// bufLen will be divisible by 16 +u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { + s32 chunkLen; + s32 i; + u32 *aiBufPtr = (u32 *) aiBuf; + u64 *cmd = cmdBuf + 1; + s32 v0; + + aSegment(cmdBuf, 0, 0); + + for (i = gAudioUpdatesPerFrame; i > 0; i--) { + if (i == 1) { + // 'bufLen' will automatically be divisible by 8, no need to round + chunkLen = bufLen; + } else { + v0 = bufLen / i; + // chunkLen = v0 rounded to nearest multiple of 8 + chunkLen = v0 - (v0 & 7); + + if ((v0 & 7) >= 4) { + chunkLen += 8; + } + } + process_sequences(i - 1); + if (gSynthesisReverb.useReverb != 0) { + prepare_reverb_ring_buffer(chunkLen, gAudioUpdatesPerFrame - i); + } + cmd = synthesis_do_one_audio_update((s16 *) aiBufPtr, chunkLen, cmd, gAudioUpdatesPerFrame - i); + bufLen -= chunkLen; + aiBufPtr += chunkLen; + } + if (gSynthesisReverb.framesLeftToIgnore != 0) { + gSynthesisReverb.framesLeftToIgnore--; + } + gSynthesisReverb.curFrame ^= 1; + *writtenCmds = cmd - cmdBuf; + return cmd; +} + + +u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { + UNUSED s32 pad1[1]; + s16 ra; + s16 t4; + UNUSED s32 pad[2]; + struct ReverbRingBufferItem *v1; + UNUSED s32 pad2[1]; + s16 temp; + + v1 = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; + + if (gSynthesisReverb.useReverb == 0) { + aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); + cmd = synthesis_process_notes(aiBuf, bufLen, cmd); + } else { + if (gReverbDownsampleRate == 1) { + // Put the oldest samples in the ring buffer into the wet channels + aSetLoadBufferPair(cmd++, 0, v1->startPos); + if (v1->lengthB != 0) { + // Ring buffer wrapped + aSetLoadBufferPair(cmd++, v1->lengthA, 0); + temp = 0; + } + + // Use the reverb sound as initial sound for this audio update + aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); + + // (Hopefully) lower the volume of the wet channels. New reverb will later be mixed into + // these channels. + aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); + // 0x8000 here is -100% + aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_WET_LEFT_CH, + /*out*/ DMEM_ADDR_WET_LEFT_CH); + } else { + // Same as above but upsample the previously downsampled samples used for reverb first + temp = 0; //! jesus christ + t4 = (v1->startPos & 7) * 2; + ra = ALIGN(v1->lengthA + t4, 4); + aSetLoadBufferPair(cmd++, 0, v1->startPos - t4 / 2); + if (v1->lengthB != 0) { + // Ring buffer wrapped + aSetLoadBufferPair(cmd++, ra, 0); + //! We need an empty statement (even an empty ';') here to make the function match (because IDO). + //! However, copt removes extraneous statements and dead code. So we need to trick copt + //! into thinking 'temp' could be undefined, and luckily the compiler optimizes out the + //! useless assignment. + ra = ra + temp; + } + aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, bufLen << 1); + aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateLeft)); + aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_RIGHT_CH, bufLen << 1); + aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateRight)); + aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); + aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_LEFT_CH, /*out*/ DMEM_ADDR_LEFT_CH); + aDMEMMove(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); + } + cmd = synthesis_process_notes(aiBuf, bufLen, cmd); + if (gReverbDownsampleRate == 1) { + aSetSaveBufferPair(cmd++, 0, v1->lengthA, v1->startPos); + if (v1->lengthB != 0) { + // Ring buffer wrapped + aSetSaveBufferPair(cmd++, v1->lengthA, v1->lengthB, 0); + } + } else { + // Downsampling is done later by CPU when RSP is done, therefore we need to have double + // buffering. Left and right buffers are adjacent in memory. + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex].toDownsampleLeft)); + gSynthesisReverb.resampleFlags = 0; + } + } + return cmd; +} + +u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { + s32 noteIndex; // sp174 + struct Note *note; // s7 + UNUSED u8 pad0[0x08]; + struct AudioBankSample *audioBookSample; // sp164, sp138 + struct AdpcmLoop *loopInfo; // sp160, sp134 + s16 *curLoadedBook = NULL; // sp154, sp130 + UNUSED u8 pad8[0x04]; + u16 resamplingRateFixedPoint; // sp5c, sp11A + s32 noteFinished; // 150 t2, sp124 + s32 restart; // 14c t3, sp120 + s32 flags; // sp148, sp11C + UNUSED u8 pad7[0x0c]; // sp100 + UNUSED s32 tempBufLen; + UNUSED u32 pad9; + s32 sp130; //sp128, sp104 + s32 nAdpcmSamplesProcessed; // signed required for US + s32 t0; + s32 s6; + u8 *sampleAddr; // sp120, spF4 + + // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange + // behavior with the break near the end of the loop, causing US and JP to need a goto instead + UNUSED s32 samplesLenInt; + s32 samplesLenAdjusted; // 108 + s32 s2; + s32 endPos; // sp110, spE4 + s32 nSamplesToProcess; // sp10c/a0, spE0 + + s32 leftRight; + s32 s3; + s32 s5; //s4 + + u32 samplesLenFixedPoint; // v1_1 + s32 nSamplesInThisIteration; // v1_2 + u32 a3; + s32 t9; + u8 *v0_2; + s32 nParts; // spE8, spBC + s32 curPart; // spE4, spB8 + + f32 resamplingRate; // f12 + s32 temp; + + s32 resampledTempLen; // spD8, spAC + u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA + + + for (noteIndex = 0; noteIndex < gMaxSimultaneousNotes; noteIndex++) { + note = &gNotes[noteIndex]; +#ifdef VERSION_US + //! This function requires note->enabled to be volatile, but it breaks other functions like note_enable. + //! Casting to a struct with just the volatile bitfield works, but there may be a better way to match. + if (((struct vNote *)note)->enabled && IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { +#else + if (IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { +#endif + gAudioErrorFlags = (note->bankId << 8) + noteIndex + 0x1000000; + } else if (((struct vNote *)note)->enabled) { + flags = 0; + + if (note->needsInit == TRUE) { + flags = A_INIT; + note->samplePosInt = 0; + note->samplePosFrac = 0; + } + + if (note->frequency < JP_DOUBLE(2.0)) { + nParts = 1; + if (note->frequency > JP_DOUBLE(1.99996)) { + note->frequency = JP_DOUBLE(1.99996); + } + resamplingRate = note->frequency; + } else { + // If frequency is > 2.0, the processing must be split into two parts + nParts = 2; + if (note->frequency >= JP_DOUBLE(3.99993)) { + note->frequency = JP_DOUBLE(3.99993); + } + resamplingRate = note->frequency * JP_DOUBLE(.5); + } + + resamplingRateFixedPoint = (u16)(s32)(resamplingRate * 32768.0f); + samplesLenFixedPoint = note->samplePosFrac + (resamplingRateFixedPoint * bufLen) * 2; + note->samplePosFrac = samplesLenFixedPoint & 0xFFFF; // 16-bit store, can't reuse + + if (note->sound == NULL) { + // A wave synthesis note (not ADPCM) + + cmd = load_wave_samples(cmd, note, samplesLenFixedPoint >> 0x10); + noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + note->samplePosInt * 2; + note->samplePosInt += (samplesLenFixedPoint >> 0x10); + flags = 0; + } + else { + // ADPCM note + + audioBookSample = note->sound->sample; + + loopInfo = audioBookSample->loop; + endPos = loopInfo->end; + sampleAddr = audioBookSample->sampleAddr; + resampledTempLen = 0; + for (curPart = 0; curPart < nParts; curPart++) { + nAdpcmSamplesProcessed = 0; // s8 + s5 = 0; // s4 + + if (nParts == 1) { + samplesLenAdjusted = samplesLenFixedPoint >> 0x10; + } else if ((samplesLenFixedPoint >> 0x10) & 1) { + samplesLenAdjusted = ((samplesLenFixedPoint >> 0x10) & ~1) + (curPart * 2); + } + else { + samplesLenAdjusted = (samplesLenFixedPoint >> 0x10); + } + + if (curLoadedBook != audioBookSample->book->book) { + u32 nEntries; // v1 + curLoadedBook = audioBookSample->book->book; + nEntries = audioBookSample->book->order * audioBookSample->book->npredictors; + aLoadADPCM(cmd++, nEntries * 16, VIRTUAL_TO_PHYSICAL2(curLoadedBook)); + } + + while (nAdpcmSamplesProcessed != samplesLenAdjusted) { + s32 samplesRemaining; // v1 + s32 s0; + + noteFinished = FALSE; + restart = FALSE; + nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; + s2 = note->samplePosInt & 0xf; + samplesRemaining = endPos - note->samplePosInt; + + if (s2 == 0 && note->restart == FALSE) { + s2 = 16; + } + s6 = 16 - s2; // a1 + + if (nSamplesToProcess < samplesRemaining) { + t0 = (nSamplesToProcess - s6 + 0xf) / 16; + s0 = t0 * 16; + s3 = s6 + s0 - nSamplesToProcess; + } else { + s0 = samplesRemaining + s2 - 0x10; + s3 = 0; + if (s0 <= 0) { + s0 = 0; + s6 = samplesRemaining; + } + t0 = (s0 + 0xf) / 16; + if (loopInfo->count != 0) { + // Loop around and restart + restart = 1; + } else { + noteFinished = 1; + } + } + + if (t0 != 0) { + temp = (note->samplePosInt - s2 + 0x10) / 16; + v0_2 = dma_sample_data( + (uintptr_t) (sampleAddr + temp * 9), + t0 * 9, flags, ¬e->sampleDmaIndex); + a3 = (u32)((uintptr_t) v0_2 & 0xf); + aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA, 0, t0 * 9 + a3); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3)); + } else { + s0 = 0; + a3 = 0; + } + + if (note->restart != FALSE) { + aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); + flags = A_LOOP; // = 2 + note->restart = FALSE; + } + + nSamplesInThisIteration = s0 + s6 - s3; + if (nAdpcmSamplesProcessed == 0) { + aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); + aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState)); + sp130 = s2 * 2; + } else { + aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5), s0 * 2); + aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState)); + aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5) + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); + } + + nAdpcmSamplesProcessed += nSamplesInThisIteration; + + switch (flags) { + case A_INIT: // = 1 + sp130 = 0; + s5 = s0 * 2 + s5; + break; + + case A_LOOP: // = 2 + s5 = nSamplesInThisIteration * 2 + s5; + break; + + default: + if (s5 != 0) { + s5 = nSamplesInThisIteration * 2 + s5; + } else { + s5 = (s2 + nSamplesInThisIteration) * 2; + } + break; + } + flags = 0; + + if (noteFinished) { + aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, + (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); + note->samplePosInt = 0; + note->finished = 1; + ((struct vNote *)note)->enabled = 0; + break; + } + if (restart) { + note->restart = TRUE; + note->samplePosInt = loopInfo->start; + } else { + note->samplePosInt += nSamplesToProcess; + } + } + + switch (nParts) { + case 1: + noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + sp130; + break; + + case 2: + switch (curPart) { + case 0: + aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED, samplesLenAdjusted + 4); + aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->dummyResampleState)); + resampledTempLen = samplesLenAdjusted + 4; + noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED + 4; + if (note->finished != FALSE) { + aClearBuffer(cmd++, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10); + } + break; + + case 1: + aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED2, samplesLenAdjusted + 8); + aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2( note->synthesisBuffers->dummyResampleState)); + aDMEMMove(cmd++, DMEM_ADDR_RESAMPLED2 + 4, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 4); + break; + } + } + + if (note->finished != FALSE) { + break; + } + } + } + + flags = 0; + + if (note->needsInit == TRUE) { + flags = A_INIT; + note->needsInit = FALSE; + } + + cmd = final_resample(cmd, note, bufLen * 2, resamplingRateFixedPoint, + noteSamplesDmemAddrBeforeResampling, flags); + + if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) { + leftRight = 1; + } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) { + leftRight = 2; + } else { + leftRight = 0; + } + + cmd = process_envelope(cmd, note, bufLen, 0, leftRight, flags); + + if (note->usesHeadsetPanEffects) { + cmd = note_apply_headset_pan_effects(cmd, note, bufLen * 2, flags, leftRight); + } + } + } + + t9 = bufLen * 2; + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); + aInterleave(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH); + t9 *= 2; + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); + + return cmd; +} + +u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { + s32 a3; + s32 i; + aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, + /*count*/ sizeof(note->synthesisBuffers->samples)); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->samples)); + note->samplePosInt &= (note->sampleCount - 1); + a3 = 64 - note->samplePosInt; + if (a3 < nSamplesToLoad) { + for (i = 0; i <= (nSamplesToLoad - a3 + 63) / 64 - 1; i++) { + aDMEMMove(cmd++, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + (1 + i) * sizeof(note->synthesisBuffers->samples), /*count*/ sizeof(note->synthesisBuffers->samples)); + } + } + return cmd; +} + +u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags) { + aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); + aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->finalResampleState)); + return cmd; +} + +u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, + UNUSED u32 flags) { + UNUSED u8 pad[16]; + struct VolumeChange vol; + vol.sourceLeft = note->curVolLeft; + vol.sourceRight = note->curVolRight; + vol.targetLeft = note->targetVolLeft; + vol.targetRight = note->targetVolRight; + note->curVolLeft = vol.targetLeft; + note->curVolRight = vol.targetRight; + return process_envelope_inner(cmd, note, nSamples, inBuf, headsetPanSettings, &vol); +} + +u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, + s32 headsetPanSettings, struct VolumeChange *vol) { + UNUSED u8 pad[3]; + u8 mixerFlags; + UNUSED u8 pad2[8]; + s32 rampLeft, rampRight; + + // For aEnvMixer, five buffers and count are set using aSetBuffer. + // in, dry left, count without A_AUX flag. + // dry right, wet left, wet right with A_AUX flag. + + if (note->usesHeadsetPanEffects) { + aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DEFAULT_LEN_1CH); + + switch (headsetPanSettings) { + case 1: + aSetBuffer(cmd++, 0, inBuf, DMEM_ADDR_NOTE_PAN_TEMP, nSamples * 2); + aSetBuffer(cmd++, A_AUX, DMEM_ADDR_RIGHT_CH, DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + break; + case 2: + aSetBuffer(cmd++, 0, inBuf, DMEM_ADDR_LEFT_CH, nSamples * 2); + aSetBuffer(cmd++, A_AUX, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + break; + default: + aSetBuffer(cmd++, 0, inBuf, DMEM_ADDR_LEFT_CH, nSamples * 2); + aSetBuffer(cmd++, A_AUX, DMEM_ADDR_RIGHT_CH, DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + break; + } + } else { + // It's a bit unclear what the "stereo strong" concept does. + // Instead of mixing the opposite channel to the normal buffers, the sound is first + // mixed into a temporary buffer and then subtracted from the normal buffer. + if (note->stereoStrongRight) { + aClearBuffer(cmd++, DMEM_ADDR_STEREO_STRONG_TEMP_DRY, DEFAULT_LEN_2CH); + aSetBuffer(cmd++, 0, inBuf, DMEM_ADDR_STEREO_STRONG_TEMP_DRY, nSamples * 2); + aSetBuffer(cmd++, A_AUX, DMEM_ADDR_RIGHT_CH, DMEM_ADDR_STEREO_STRONG_TEMP_WET, + DMEM_ADDR_WET_RIGHT_CH); + } else if (note->stereoStrongLeft) { + aClearBuffer(cmd++, DMEM_ADDR_STEREO_STRONG_TEMP_DRY, DEFAULT_LEN_2CH); + aSetBuffer(cmd++, 0, inBuf, DMEM_ADDR_LEFT_CH, nSamples * 2); + aSetBuffer(cmd++, A_AUX, DMEM_ADDR_STEREO_STRONG_TEMP_DRY, DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_STEREO_STRONG_TEMP_WET); + } else { + aSetBuffer(cmd++, 0, inBuf, DMEM_ADDR_LEFT_CH, nSamples * 2); + aSetBuffer(cmd++, A_AUX, DMEM_ADDR_RIGHT_CH, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_RIGHT_CH); + } + } + + if (vol->targetLeft == vol->sourceLeft && vol->targetRight == vol->sourceRight + && !note->envMixerNeedsInit) { + mixerFlags = A_CONTINUE; + } else { + mixerFlags = A_INIT; + + rampLeft = get_volume_ramping(vol->sourceLeft, vol->targetLeft, nSamples); + rampRight = get_volume_ramping(vol->sourceRight, vol->targetRight, nSamples); + + // The operation's parameters change meanings depending on flags + aSetVolume(cmd++, A_VOL | A_LEFT, vol->sourceLeft, 0, 0); + aSetVolume(cmd++, A_VOL | A_RIGHT, vol->sourceRight, 0, 0); + aSetVolume32(cmd++, A_RATE | A_LEFT, vol->targetLeft, rampLeft); + aSetVolume32(cmd++, A_RATE | A_RIGHT, vol->targetRight, rampRight); + aSetVolume(cmd++, A_AUX, gVolume, 0, note->reverbVolShifted); + } + + if (gSynthesisReverb.useReverb && note->reverbVol != 0) { + aEnvMixer(cmd++, mixerFlags | A_AUX, + VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); + if (note->stereoStrongRight) { + aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); + // 0x8000 is -100%, so subtract sound instead of adding... + aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_DRY, + /*out*/ DMEM_ADDR_LEFT_CH); + aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_WET, + /*out*/ DMEM_ADDR_WET_LEFT_CH); + } else if (note->stereoStrongLeft) { + aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); + aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_DRY, + /*out*/ DMEM_ADDR_RIGHT_CH); + aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_WET, + /*out*/ DMEM_ADDR_WET_RIGHT_CH); + } + } else { + aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); + if (note->stereoStrongRight) { + aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); + aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_DRY, + /*out*/ DMEM_ADDR_LEFT_CH); + } else if (note->stereoStrongLeft) { + aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); + aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_DRY, + /*out*/ DMEM_ADDR_RIGHT_CH); + } + } + return cmd; +} + +u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight) { + u16 dest; + u16 pitch; + u16 prevPanShift; + u16 panShift; + + switch (leftRight) { + case 1: + dest = DMEM_ADDR_LEFT_CH; + panShift = note->headsetPanRight; + note->prevHeadsetPanLeft = 0; + prevPanShift = note->prevHeadsetPanRight; + note->prevHeadsetPanRight = panShift; + break; + case 2: + dest = DMEM_ADDR_RIGHT_CH; + panShift = note->headsetPanLeft; + note->prevHeadsetPanRight = 0; + + prevPanShift = note->prevHeadsetPanLeft; + note->prevHeadsetPanLeft = panShift; + break; + default: + return cmd; + } + + if (flags != 1) { // A_INIT? + // Slightly adjust the sample rate in order to fit a change in pan shift + if (prevPanShift == 0) { + // Kind of a hack that moves the first samples into the resample state + aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, 8); + aClearBuffer(cmd++, 8, 8); // Set pitch accumulator to 0 in the resample state + aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP + 0x10, + 0x10); // No idea, result seems to be overwritten later + + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, 32); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); + + pitch = (bufLen << 0xf) / (panShift + bufLen - prevPanShift + 8); + aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP + 8, DMEM_ADDR_TEMP, panShift + bufLen - prevPanShift); + aResample(cmd++, 0, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); + } else { + if (panShift == 0) { + pitch = (bufLen << 0xf) / (bufLen - prevPanShift - 4); + } else { + pitch = (bufLen << 0xf) / (bufLen + panShift - prevPanShift); + } + + aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, panShift + bufLen - prevPanShift); + aResample(cmd++, 0, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); + } + + if (prevPanShift != 0) { + aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP, 0, prevPanShift); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer)); + aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + prevPanShift, panShift + bufLen - prevPanShift); + } else { + aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP, panShift + bufLen - prevPanShift); + } + } else { + // Just shift right + aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen); + aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + panShift, bufLen); + aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, panShift); + } + + if (panShift) { + // Save excessive samples for next iteration + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_NOTE_PAN_TEMP + bufLen, panShift); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer)); + } + + aSetBuffer(cmd++, 0, 0, 0, bufLen); + aMix(cmd++, 0, /*gain*/ 0x7fff, /*in*/ DMEM_ADDR_NOTE_PAN_TEMP, /*out*/ dest); + + return cmd; +} + +// Moved to playback.c in EU + +void note_init_volume(struct Note *note) { + note->targetVolLeft = 0; + note->targetVolRight = 0; + note->reverbVol = 0; + note->reverbVolShifted = 0; + note->unused2 = 0; + note->curVolLeft = 1; + note->curVolRight = 1; + note->frequency = 0.0f; +} + +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol) { + s32 panIndex; + f32 volLeft; + f32 volRight; + // Anding with 127 avoids out-of-bounds reads when pan is outside of [0, 1]. + // This can occur during PU movement -- see the bug comment in get_sound_pan + // in external.c. An out-of-bounds read by itself doesn't crash, but if the + // resulting value is a nan or denormal, performing arithmetic on it crashes + // on console. +#ifdef VERSION_JP + panIndex = MIN((s32)(pan * 127.5), 127); +#else + panIndex = (s32)(pan * 127.5f) & 127; +#endif + if (note->stereoHeadsetEffects && gSoundMode == SOUND_MODE_HEADSET) { + s8 smallPanIndex; + s8 temp = (s8)(pan * 10.0f); + if (temp < 9) { + smallPanIndex = temp; + } else { + smallPanIndex = 9; + } + note->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; + note->headsetPanRight = gHeadsetPanQuantization[9 - smallPanIndex]; + note->stereoStrongRight = FALSE; + note->stereoStrongLeft = FALSE; + note->usesHeadsetPanEffects = TRUE; + volLeft = gHeadsetPanVolume[panIndex]; + volRight = gHeadsetPanVolume[127 - panIndex]; + } else if (note->stereoHeadsetEffects && gSoundMode == SOUND_MODE_STEREO) { + u8 strongLeft; + u8 strongRight; + strongLeft = FALSE; + strongRight = FALSE; + note->headsetPanLeft = 0; + note->headsetPanRight = 0; + note->usesHeadsetPanEffects = FALSE; + volLeft = gStereoPanVolume[panIndex]; + volRight = gStereoPanVolume[127 - panIndex]; + if (panIndex < 0x20) { + strongLeft = TRUE; + } else if (panIndex > 0x60) { + strongRight = TRUE; + } + note->stereoStrongRight = strongRight; + note->stereoStrongLeft = strongLeft; + } else if (gSoundMode == SOUND_MODE_MONO) { + volLeft = .707f; + volRight = .707f; + } else { + volLeft = gDefaultPanVolume[panIndex]; + volRight = gDefaultPanVolume[127 - panIndex]; + } + + if (velocity < 0) { + velocity = 0; + } +#ifdef VERSION_JP + note->targetVolLeft = (u16)(velocity * volLeft) & ~0x80FF; // 0x7F00, but that doesn't match + note->targetVolRight = (u16)(velocity * volRight) & ~0x80FF; +#else + note->targetVolLeft = (u16)(s32)(velocity * volLeft) & ~0x80FF; + note->targetVolRight = (u16)(s32)(velocity * volRight) & ~0x80FF; +#endif + if (note->targetVolLeft == 0) { + note->targetVolLeft++; + } + if (note->targetVolRight == 0) { + note->targetVolRight++; + } + if (note->reverbVol != reverbVol) { + note->reverbVol = reverbVol; + note->reverbVolShifted = reverbVol << 8; + note->envMixerNeedsInit = TRUE; + return; + } + + if (note->needsInit) { + note->envMixerNeedsInit = TRUE; + } else { + note->envMixerNeedsInit = FALSE; + } +} + +void note_set_frequency(struct Note *note, f32 frequency) { + note->frequency = frequency; +} + +void note_enable(struct Note *note) { + note->enabled = TRUE; + note->needsInit = TRUE; + note->restart = FALSE; + note->finished = FALSE; + note->stereoStrongRight = FALSE; + note->stereoStrongLeft = FALSE; + note->usesHeadsetPanEffects = FALSE; + note->headsetPanLeft = 0; + note->headsetPanRight = 0; + note->prevHeadsetPanRight = 0; + note->prevHeadsetPanLeft = 0; +} + +void note_disable(struct Note *note) { + if (note->needsInit == TRUE) { + note->needsInit = FALSE; + } else { + note_set_vel_pan_reverb(note, 0, .5, 0); + } + note->priority = NOTE_PRIORITY_DISABLED; + note->enabled = FALSE; + note->finished = FALSE; + note->parentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; +} diff --git a/src/audio/us_jp/synthesis.h b/src/audio/us_jp/synthesis.h new file mode 100644 index 00000000..be885c83 --- /dev/null +++ b/src/audio/us_jp/synthesis.h @@ -0,0 +1,50 @@ +#ifndef AUDIO_SYNTHESIS_H +#define AUDIO_SYNTHESIS_H + +#include "internal.h" + +#define DEFAULT_LEN_1CH 0x140 +#define DEFAULT_LEN_2CH 0x280 + +#define MAX_UPDATES_PER_FRAME 4 + +struct ReverbRingBufferItem { + s16 numSamplesAfterDownsampling; + s16 chunkLen; // never read + s16 *toDownsampleLeft; + s16 *toDownsampleRight; // data pointed to by left and right are adjacent in memory + s32 startPos; // start pos in ring buffer + s16 lengthA; // first length in ring buffer (from startPos, at most until end) + s16 lengthB; // second length in ring buffer (from pos 0) +}; // size = 0x14 + +struct SynthesisReverb { + /*0x00, 0x00, 0x00*/ u8 resampleFlags; + /*0x01, 0x01, 0x01*/ u8 useReverb; + /*0x02, 0x02, 0x02*/ u8 framesLeftToIgnore; + /*0x03, 0x03, 0x03*/ u8 curFrame; + /*0x04, 0x08, 0x0A*/ u16 reverbGain; + /*0x06, 0x0A, 0x0C*/ u16 resampleRate; + /*0x08, 0x0C, 0x14*/ s32 nextRingBufferPos; + /*0x0C, 0x10, 0x18*/ s32 unkC; // never read + /*0x10, 0x14, 0x1C*/ s32 bufSizePerChannel; + struct { + s16 *left; + s16 *right; + } ringBuffer; + /*0x1C, 0x20, 0x28*/ s16 *resampleStateLeft; + /*0x20, 0x24, 0x2C*/ s16 *resampleStateRight; + /*0x24, 0x28, 0x30*/ s16 *unk24; // never read + /*0x28, 0x2C, 0x34*/ s16 *unk28; // never read + /*0x2C, 0x30, 0x38*/ struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME]; +}; // 0xCC <= size <= 0x100 +extern struct SynthesisReverb gSynthesisReverb; + +u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen); +void note_init_volume(struct Note *note); +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol); +void note_set_frequency(struct Note *note, f32 frequency); +void note_enable(struct Note *note); +void note_disable(struct Note *note); + +#endif // AUDIO_SYNTHESIS_H diff --git a/src/engine/geo_layout.c b/src/engine/geo_layout.c index 2fd4afac..594ac11b 100644 --- a/src/engine/geo_layout.c +++ b/src/engine/geo_layout.c @@ -1,4 +1,5 @@ -#include +#include +#include #include "sm64.h" #include "geo_layout.h" diff --git a/src/game/area.c b/src/game/area.c index 0c56be39..aed63358 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -1,6 +1,5 @@ #include -#include "prevent_bss_reordering.h" #include "area.h" #include "sm64.h" #include "gfx_dimensions.h" @@ -23,6 +22,8 @@ #include "level_table.h" #include "dialog_ids.h" +#include + struct SpawnInfo gPlayerSpawnInfos[1]; struct GraphNode *D_8033A160[0x100]; struct Area gAreaData[8]; diff --git a/src/game/camera.c b/src/game/camera.c index 0925e961..8afc35de 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -2,7 +2,6 @@ #define INCLUDED_FROM_CAMERA_C -#include "prevent_bss_reordering.h" #include "sm64.h" #include "camera.h" #include "seq_ids.h" diff --git a/src/game/cn_common_syms_1.c b/src/game/cn_common_syms_1.c index 6dd4b66e..79f0843f 100644 --- a/src/game/cn_common_syms_1.c +++ b/src/game/cn_common_syms_1.c @@ -7,19 +7,19 @@ #ifdef VERSION_CN FORCE_BSS u32 __osBaseCounter; FORCE_BSS s16 gSaveOptSelectIndex; -FORCE_BSS s32 sNumCountOverflows; -FORCE_BSS s32 sLastHighestCount; +FORCE_BSS s32 __osBbRCountWraps; +FORCE_BSS s32 __osBbLastRCount; FORCE_BSS u32 __osViIntrCount; FORCE_BSS s16 gCurrActNum; FORCE_BSS u8 __osMaxControllers; FORCE_BSS OSTime __osCurrentTime; FORCE_BSS s16 gMenuOptSelectIndex; -FORCE_BSS s32 sLastHighestCount2; +FORCE_BSS s32 __osBbLastVCount; FORCE_BSS u8 __osContLastCmd; FORCE_BSS OSMesg __osEepromTimerMsg; FORCE_BSS u32 __osTimerCounter; FORCE_BSS s16 gCurrAreaIndex; -FORCE_BSS s32 sNumCountOverflows2; +FORCE_BSS s32 __osBbVCountWraps; FORCE_BSS struct MemoryPool *gEffectsMemoryPool; FORCE_BSS s8 gNeverEnteredCastle; FORCE_BSS s8 gRedCoinsCollected; diff --git a/src/game/cn_common_syms_2.c b/src/game/cn_common_syms_2.c index d817ca05..6906bc38 100644 --- a/src/game/cn_common_syms_2.c +++ b/src/game/cn_common_syms_2.c @@ -84,20 +84,20 @@ struct Area { FORCE_BSS struct HudDisplay gHudDisplay; FORCE_BSS OSThread __osThreadSave; -FORCE_BSS OSPifRam __osContPifRam; +FORCE_BSS ALIGNED16 OSPifRam __osContPifRam; FORCE_BSS OSPiHandle __Dom2SpeedParam; FORCE_BSS struct SpawnInfo gPlayerSpawnInfos[1]; FORCE_BSS struct GraphNode *D_8033A160[0x100]; FORCE_BSS OSPiHandle __CartRomHandle; FORCE_BSS u8 sBssPad[0x48]; //! TODO: What is this space in the bss? -FORCE_BSS OSMesgQueue gOsPiMessageQueue; +FORCE_BSS ALIGNED8 OSMesgQueue __osPiAccessQueue; FORCE_BSS OSPiHandle __Dom1SpeedParam; FORCE_BSS OSTimer __osBaseTimer; FORCE_BSS struct WarpTransition gWarpTransition; FORCE_BSS OSTimer __osEepromTimer; FORCE_BSS struct MarioState gMarioStates[1]; FORCE_BSS __OSEventState __osEventStateTab[OS_NUM_EVENTS]; -FORCE_BSS OSMesgQueue __osEepromTimerQ; +FORCE_BSS ALIGNED8 OSMesgQueue __osEepromTimerQ; FORCE_BSS struct Area gAreaData[8]; -FORCE_BSS OSMesgQueue gOsSiMessageQueue; +FORCE_BSS ALIGNED8 OSMesgQueue __osSiAccessQueue; #endif diff --git a/src/game/crash_screen.c b/src/game/crash_screen.c index 5381bc18..574b1103 100644 --- a/src/game/crash_screen.c +++ b/src/game/crash_screen.c @@ -5,8 +5,8 @@ #include "sm64.h" #if defined(TARGET_N64) && (defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN)) - -#include "lib/src/printf.h" +#include "PR/os_internal.h" +#include "lib/ultra/libc/xstdio.h" u8 gCrashScreenCharToGlyph[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, diff --git a/src/game/envfx_snow.c b/src/game/envfx_snow.c index f421bc47..b4a4772e 100644 --- a/src/game/envfx_snow.c +++ b/src/game/envfx_snow.c @@ -1,4 +1,5 @@ #include +#include #include "sm64.h" #include "dialog_ids.h" diff --git a/src/game/envfx_snow.h b/src/game/envfx_snow.h index 378dae9a..952baf72 100644 --- a/src/game/envfx_snow.h +++ b/src/game/envfx_snow.h @@ -29,11 +29,11 @@ struct EnvFxParticle { }; extern s8 gEnvFxMode; -extern UNUSED s32 D_80330644; extern struct EnvFxParticle *gEnvFxBuffer; extern Vec3i gSnowCylinderLastPos; extern s16 gSnowParticleCount; +extern s16 gSnowParticleMaxCount; Gfx *envfx_update_particles(s32 mode, Vec3s marioPos, Vec3s camTo, Vec3s camFrom); void orbit_from_positions(Vec3s from, Vec3s to, s16 *radius, s16 *pitch, s16 *yaw); diff --git a/src/game/game_init.c b/src/game/game_init.c index 89da5bf5..6775eeda 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -55,8 +55,8 @@ struct DmaHandlerList gMarioAnimsBuf; struct DmaHandlerList gDemoInputsBuf; // fillers -UNUSED static u8 sfillerGameInit[0x90]; -static s32 sUnusedGameInitValue = 0; +UNUSED u8 sfillerGameInit[0x90]; // not static because of bss +s32 sUnusedGameInitValue = 0; // General timer that runs as the game starts u32 gGlobalTimer = 0; diff --git a/src/game/game_init.h b/src/game/game_init.h index 4ab929e0..94a77b4a 100644 --- a/src/game/game_init.h +++ b/src/game/game_init.h @@ -41,6 +41,9 @@ extern u8 *gGfxPoolEnd; extern struct GfxPool *gGfxPool; extern u8 gControllerBits; extern s8 gEepromProbe; +extern struct DmaHandlerList gMarioAnimsBuf; +extern struct DmaHandlerList gDemoInputsBuf; +extern UNUSED u8 sfillerGameInit[0x90]; extern void (*gGoddardVblankCallback)(void); extern struct Controller *gPlayer1Controller; diff --git a/src/game/level_update.c b/src/game/level_update.c index a6186c38..4b045ea3 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -1,4 +1,5 @@ #include +#include #include "sm64.h" #include "seq_ids.h" diff --git a/src/game/main.c b/src/game/main.c index 4d8bf9b7..34e8986f 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -426,7 +426,7 @@ void thread1_idle(UNUSED void *arg) { osCreateViManager(OS_PRIORITY_VIMGR); #if defined(VERSION_US) || defined(VERSION_SH) || defined(VERSION_CN) - if (sp24 == TV_TYPE_NTSC) { + if (sp24 == OS_TV_NTSC) { osViSetMode(&osViModeTable[OS_VI_NTSC_LAN1]); } else { osViSetMode(&osViModeTable[OS_VI_PAL_LAN1]); diff --git a/src/game/mario.c b/src/game/mario.c index 32c63c90..dac39b9b 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -33,6 +33,8 @@ #include "sound_init.h" #include "rumble_init.h" +typedef int bss_reordering_fix; + u32 unused80339F10; u8 unused80339F1C[20]; diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index fcee2c29..18adfd7c 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -1,6 +1,5 @@ #include -#include "prevent_bss_reordering.h" #include "sm64.h" #include "area.h" #include "audio/external.h" @@ -15,7 +14,6 @@ #include "gfx_dimensions.h" #include "ingame_menu.h" #include "interaction.h" -#include "level_table.h" #include "level_update.h" #include "mario.h" #include "mario_actions_cutscene.h" @@ -29,15 +27,6 @@ #include "sound_init.h" #include "rumble_init.h" -static struct Object *sIntroWarpPipeObj; -static struct Object *sEndPeachObj; -static struct Object *sEndRightToadObj; -static struct Object *sEndLeftToadObj; -static struct Object *sEndJumboStarObj; -static UNUSED s32 sUnused; -static s16 sEndPeachAnimation; -static s16 sEndToadAnims[2]; - static Vp sEndCutsceneVp = { { { 640, 480, 511, 0 }, { 640, 480, 511, 0 } } }; static struct CreditsEntry *sDispCreditsEntry = NULL; @@ -48,6 +37,15 @@ static s8 D_8032CBEC[7] = { 2, 3, 2, 1, 2, 3, 2 }; static u8 sStarsNeededForDialog[] = { 1, 3, 8, 30, 50, 70 }; +struct Object *sIntroWarpPipeObj; +struct Object *sEndPeachObj; +struct Object *sEndRightToadObj; +struct Object *sEndLeftToadObj; +struct Object *sEndJumboStarObj; +struct Object *sEndUnusedObj; +s16 sEndPeachAnimation; +s16 sEndToadAnims[2]; + /** * Data for the jumbo star cutscene. It specifies the flight path after triple * jumping. Each entry is one keyframe. diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 4fc919f7..0c05e9c1 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -1,4 +1,5 @@ #include +#include #include "sm64.h" #include "level_update.h" diff --git a/src/game/object_list_processor.h b/src/game/object_list_processor.h index 5bea549f..cd7534cb 100644 --- a/src/game/object_list_processor.h +++ b/src/game/object_list_processor.h @@ -7,6 +7,8 @@ #include "macros.h" #include "types.h" +#include + /** * Flags for gTimeStopState. These control which objects are processed each frame * and also track some miscellaneous info. diff --git a/src/game/save_file.h b/src/game/save_file.h index ad1b62a9..2cf80afe 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -8,7 +8,6 @@ #include "course_table.h" -#define EEPROM_SIZE 0x200 #define NUM_SAVE_FILES 4 struct SaveBlockSignature { diff --git a/src/goddard/joints.c b/src/goddard/joints.c index 53dc6677..50a93307 100644 --- a/src/goddard/joints.c +++ b/src/goddard/joints.c @@ -1,9 +1,5 @@ #include -#if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN) -#include "prevent_bss_reordering.h" -#endif - #include "debug_utils.h" #include "draw_objects.h" #include "dynlist_proc.h" diff --git a/src/goddard/renderer.c b/src/goddard/renderer.c index 294f16c4..b8f2c499 100644 --- a/src/goddard/renderer.c +++ b/src/goddard/renderer.c @@ -2,6 +2,8 @@ #include #include +#include + #include "debug_utils.h" #include "draw_objects.h" #include "dynlist_proc.h" diff --git a/src/goddard/shape_helper.c b/src/goddard/shape_helper.c index c811c918..d336738a 100644 --- a/src/goddard/shape_helper.c +++ b/src/goddard/shape_helper.c @@ -1,9 +1,5 @@ #include -#if defined(VERSION_JP) || defined(VERSION_US) -#include "prevent_bss_reordering.h" -#endif - #include "debug_utils.h" #include "draw_objects.h" #include "dynlist_proc.h" diff --git a/tools/.gitignore b/tools/.gitignore index 1abd8943..7463b430 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -11,3 +11,4 @@ !/ido5.3_compiler/usr/lib/*.so !/ido5.3_compiler/usr/lib/*.so.1 !/ido5.3_compiler/**/*.o +!/ld/libbfd-2.30.so diff --git a/tools/armips.cpp b/tools/armips.cpp index 271bf558..2e26cf94 100644 --- a/tools/armips.cpp +++ b/tools/armips.cpp @@ -32,7 +32,6 @@ SOFTWARE. #define _CRT_SECURE_NO_WARNINGS -#undef __STRICT_ANSI__ #if defined(__clang__) #if __has_feature(cxx_exceptions) diff --git a/tools/assemble_sound.py b/tools/assemble_sound.py index 46406b16..20286a97 100755 --- a/tools/assemble_sound.py +++ b/tools/assemble_sound.py @@ -66,7 +66,7 @@ def validate(cond, msg, forstr=""): def strip_comments(string): - string = re.sub(re.compile("/\*.*?\*/", re.DOTALL), "", string) + string = re.sub(re.compile(r"/\*.*?\*/", re.DOTALL), "", string) return re.sub(re.compile("//.*?\n"), "", string) diff --git a/tools/clang-tidy.sh b/tools/clang-tidy.sh index 22481433..85e6d6f9 100755 --- a/tools/clang-tidy.sh +++ b/tools/clang-tidy.sh @@ -28,7 +28,7 @@ echo "Tidying all C files for all versions. This will take a bit" for VER in ${VERSIONS}; do echo "Tidying for compiler version flag ${VER}" # Don't run clang-tidy on behaviors - clang-tidy ${TIDY_OPTS} src/audio/*.c -- ${COMPILER_OPTS} ${VER} + clang-tidy ${TIDY_OPTS} src/audio/*.c src/audio/*/*.c -- ${COMPILER_OPTS} ${VER} clang-tidy ${TIDY_OPTS} src/engine/*.c -- ${COMPILER_OPTS} ${VER} clang-tidy ${TIDY_OPTS} src/game/*.c -- ${COMPILER_OPTS} ${VER} clang-tidy ${TIDY_OPTS} src/goddard/*.c -- ${COMPILER_OPTS} ${VER} diff --git a/tools/ique_egcs/as b/tools/egcs/as similarity index 100% rename from tools/ique_egcs/as rename to tools/egcs/as diff --git a/tools/ique_egcs/cc1 b/tools/egcs/cc1 similarity index 100% rename from tools/ique_egcs/cc1 rename to tools/egcs/cc1 diff --git a/tools/ique_egcs/cpp b/tools/egcs/cpp similarity index 100% rename from tools/ique_egcs/cpp rename to tools/egcs/cpp diff --git a/tools/ique_egcs/gcc b/tools/egcs/gcc similarity index 100% rename from tools/ique_egcs/gcc rename to tools/egcs/gcc diff --git a/tools/ique_ld/libbfd-2.30.so b/tools/ld/libbfd-2.30.so similarity index 100% rename from tools/ique_ld/libbfd-2.30.so rename to tools/ld/libbfd-2.30.so diff --git a/tools/ique_ld/mips64-elf-ld b/tools/ld/mips64-elf-ld similarity index 100% rename from tools/ique_ld/mips64-elf-ld rename to tools/ld/mips64-elf-ld diff --git a/undefined_syms.txt b/undefined_syms.txt deleted file mode 100644 index 938137ac..00000000 --- a/undefined_syms.txt +++ /dev/null @@ -1,74 +0,0 @@ -/* libultra OS symbols */ - -/* boot and osException symbols */ - -/* exceptions */ - -EXCEPTION_TLB_MISS = 0x80000000; - -/* SP */ - -SP_DMEM = 0xA4000000; -SP_DMEM_UNK0 = 0xA40004C0; -SP_DMEM_UNK1 = 0xA4000774; -SP_IMEM = 0xA4001000; -SP_STATUS_REG = 0xA4040010; -SP_PC = 0xA4080000; - -D_CN_0400049C = 0x0400049C; -D_CN_0400074C = 0x0400074C; - -/* MI */ - -MI_MODE_REG = 0xA4300000; -MI_VERSION_REG = 0xA4300004; -MI_INTR_REG = 0xA4300008; -MI_INTR_MASK_REG = 0xA430000C; - -/* VI */ - -VI_CURRENT_REG = 0xA4400010; - -/* AI */ - -AI_STATUS_REG = 0xA450000C; - -/* PI */ - -PI_DRAM_ADDR_REG = 0xA4600000; -PI_CART_ADDR_REG = 0xA4600004; -PI_WR_LEN_REG = 0xA460000C; -PI_STATUS_REG = 0xA4600010; -PI_BSD_DOM1_LAT_REG = 0xA4600014; -PI_BSD_DOM1_PWD_REG = 0xA4600018; -PI_BSD_DOM1_PGS_REG = 0xA460001C; -PI_BSD_DOM1_RLS_REG = 0xA4600020; - -/* RI */ - -RI_MODE_REG = 0xA4700000; -RI_REFRESH_REG = 0xA4700010; - -/* SI */ - -SI_STATUS_REG = 0xA4800018; - -/* Unknown */ -D_B0000008 = 0xB0000008; -D_B0000010 = 0xB0000010; -D_B0000014 = 0xB0000014; -D_C0000000 = 0xC0000000; -D_C0000008 = 0xC0000008; -D_C000000C = 0xC000000C; - -/* iQue symbols */ -__osBbEepromAddress = 0x8000035C; -__osBbEepromSize = 0x80000360; -__osBbFlashAddress = 0x80000364; -__osBbFlashSize = 0x80000368; -__osBbSramAddress = 0x8000036C; -__osBbSramSize = 0x80000370; -__osBbPakAddress = 0x80000374; -__osBbPakSize = 0x80000384; -__osBbIsBb = 0x80000388; -__osBbHackFlags = 0x8000038C;