You've already forked pico-loader
mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-01-09 16:28:35 -08:00
Initial commit
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.bin binary
|
||||||
59
.github/workflows/nightly.yml
vendored
Normal file
59
.github/workflows/nightly.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
name: Build Pico Loader
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["develop"]
|
||||||
|
paths-ignore:
|
||||||
|
- 'README.md'
|
||||||
|
pull_request:
|
||||||
|
branches: ["develop"]
|
||||||
|
paths-ignore:
|
||||||
|
- 'README.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pico_loader:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
platform: [
|
||||||
|
"ACE3DS",
|
||||||
|
"AK2",
|
||||||
|
"AKRPG",
|
||||||
|
"DSPICO",
|
||||||
|
"DSTT",
|
||||||
|
"G003",
|
||||||
|
"M3DS",
|
||||||
|
"R4",
|
||||||
|
"R4iDSN",
|
||||||
|
"SUPERCARD"
|
||||||
|
]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: skylyrac/blocksds:slim-v1.13.1
|
||||||
|
name: Build Pico Loader
|
||||||
|
env:
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
|
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||||
|
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: 9.x
|
||||||
|
- name: Run build script
|
||||||
|
run: |
|
||||||
|
make PICO_PLATFORM=${{ matrix.platform }}
|
||||||
|
mv picoLoader7.bin data/picoLoader7.bin
|
||||||
|
mv picoLoader9_${{ matrix.platform }}.bin data/picoLoader9.bin
|
||||||
|
- name: Publish build to GH Actions
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
data/aplist.bin
|
||||||
|
data/savelist.bin
|
||||||
|
data/picoLoader7.bin
|
||||||
|
data/picoLoader9.bin
|
||||||
|
name: Pico Loader for ${{ matrix.platform }}
|
||||||
52
.gitignore
vendored
Normal file
52
.gitignore
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Ignore build directories #
|
||||||
|
############################
|
||||||
|
Debug/
|
||||||
|
Release/
|
||||||
|
build/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Compiled source #
|
||||||
|
###################
|
||||||
|
*.com
|
||||||
|
*.class
|
||||||
|
*.dll
|
||||||
|
*.d
|
||||||
|
*.map
|
||||||
|
*.o
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Packages #
|
||||||
|
############
|
||||||
|
# it's better to unpack these files and commit the raw source
|
||||||
|
# git has its own built in compression methods
|
||||||
|
*.7z
|
||||||
|
*.dmg
|
||||||
|
*.gz
|
||||||
|
*.iso
|
||||||
|
*.jar
|
||||||
|
*.rar
|
||||||
|
*.tar
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# Logs and databases #
|
||||||
|
######################
|
||||||
|
*.log
|
||||||
|
*.sql
|
||||||
|
*.sqlite
|
||||||
|
|
||||||
|
# OS generated files #
|
||||||
|
######################
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
*.nds
|
||||||
|
*.elf
|
||||||
|
*.a
|
||||||
|
picoLoader*.bin
|
||||||
|
.vscode/
|
||||||
|
data/aplist.bin
|
||||||
|
data/savelist.bin
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libs/libtwl"]
|
||||||
|
path = libs/libtwl
|
||||||
|
url = https://github.com/Gericom/libtwl.git
|
||||||
17
LICENSE.txt
Normal file
17
LICENSE.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Copyright (c) 2025 LNH team
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
28
Makefile
Normal file
28
Makefile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
.PHONY: loader9 loader7 clean
|
||||||
|
|
||||||
|
all: checklibtwl loader9 loader7 apList saveList
|
||||||
|
|
||||||
|
PICO_PLATFORM ?= DSPICO
|
||||||
|
|
||||||
|
checklibtwl:
|
||||||
|
$(MAKE) -C libs/libtwl
|
||||||
|
|
||||||
|
loader9: checklibtwl
|
||||||
|
$(MAKE) -f Makefile.arm9 PLATFORM=$(PICO_PLATFORM)
|
||||||
|
|
||||||
|
loader7: checklibtwl
|
||||||
|
$(MAKE) -f Makefile.arm7
|
||||||
|
|
||||||
|
picoLoaderConverter:
|
||||||
|
dotnet build tools/PicoLoaderConverter/PicoLoaderConverter.sln
|
||||||
|
|
||||||
|
apList: picoLoaderConverter data/aplist.csv
|
||||||
|
dotnet tools/PicoLoaderConverter/PicoLoaderConverter/bin/Debug/net9.0/PicoLoaderConverter.dll aplist -i data/aplist.csv -o data/aplist.bin
|
||||||
|
|
||||||
|
saveList: picoLoaderConverter data/savelist.csv
|
||||||
|
dotnet tools/PicoLoaderConverter/PicoLoaderConverter/bin/Debug/net9.0/PicoLoaderConverter.dll savelist -i data/savelist.csv -o data/savelist.bin
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -f Makefile.arm7 clean
|
||||||
|
$(MAKE) -f Makefile.arm9 clean
|
||||||
|
rm -rf build
|
||||||
192
Makefile.arm7
Normal file
192
Makefile.arm7
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
# SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||||
|
|
||||||
|
export BLOCKSDS ?= /opt/blocksds/core
|
||||||
|
export BLOCKSDSEXT ?= /opt/blocksds/external
|
||||||
|
|
||||||
|
export LIBTWL ?= $(shell pwd)/libs/libtwl
|
||||||
|
|
||||||
|
export WONDERFUL_TOOLCHAIN ?= /opt/wonderful
|
||||||
|
ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/
|
||||||
|
|
||||||
|
# Source code paths
|
||||||
|
# -----------------
|
||||||
|
|
||||||
|
SOURCEDIRS := arm7/source common
|
||||||
|
INCLUDEDIRS := arm7/source common
|
||||||
|
BINDIRS :=
|
||||||
|
|
||||||
|
# Defines passed to all files
|
||||||
|
# ---------------------------
|
||||||
|
|
||||||
|
DEFINES := -DLIBTWL_ARM7 -DARM7
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
# ---------
|
||||||
|
|
||||||
|
LIBS := -ltwl7
|
||||||
|
LIBDIRS := $(BLOCKSDS)/libs/libnds \
|
||||||
|
$(LIBTWL)/libtwl7 $(LIBTWL)/common $(LIBTWL)
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
# -----------------
|
||||||
|
|
||||||
|
NAME := picoLoader7
|
||||||
|
BUILDDIR := build/$(NAME)
|
||||||
|
BIN := $(NAME).bin
|
||||||
|
ELF := build/$(NAME).elf
|
||||||
|
DUMP := build/$(NAME).dump
|
||||||
|
MAP := build/$(NAME).map
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
# -----
|
||||||
|
|
||||||
|
PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi-
|
||||||
|
CC := $(PREFIX)gcc
|
||||||
|
CXX := $(PREFIX)g++
|
||||||
|
LD := $(PREFIX)gcc
|
||||||
|
OBJCOPY := $(PREFIX)objcopy
|
||||||
|
OBJDUMP := $(PREFIX)objdump
|
||||||
|
MKDIR := mkdir
|
||||||
|
RM := rm -rf
|
||||||
|
|
||||||
|
# Verbose flag
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
ifeq ($(VERBOSE),1)
|
||||||
|
V :=
|
||||||
|
else
|
||||||
|
V := @
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Source files
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
ifneq ($(BINDIRS),)
|
||||||
|
SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin")
|
||||||
|
INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS))
|
||||||
|
endif
|
||||||
|
|
||||||
|
SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s")
|
||||||
|
SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c")
|
||||||
|
SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp")
|
||||||
|
|
||||||
|
# Compiler and linker flags
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
ARCH := -mthumb -mthumb-interwork -mcpu=arm7tdmi
|
||||||
|
|
||||||
|
WARNFLAGS := -Wall
|
||||||
|
|
||||||
|
ifeq ($(SOURCES_CPP),)
|
||||||
|
LIBS += -lc
|
||||||
|
else
|
||||||
|
LIBS += -lstdc++ -lc
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \
|
||||||
|
$(foreach path,$(LIBDIRS),-I$(path)/include)
|
||||||
|
|
||||||
|
LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib)
|
||||||
|
|
||||||
|
ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \
|
||||||
|
$(ARCH) -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \
|
||||||
|
$(ARCH) -O2 -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
CXXFLAGS += -std=gnu++23 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \
|
||||||
|
$(ARCH) -O2 -ffunction-sections -fdata-sections \
|
||||||
|
-fno-exceptions -fno-rtti \
|
||||||
|
-fno-threadsafe-statics \
|
||||||
|
-Wno-volatile -Wsuggest-override \
|
||||||
|
-Werror=suggest-override -Werror=return-type
|
||||||
|
|
||||||
|
LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) $(DEFINES) \
|
||||||
|
-Wl,-Map,$(MAP),--gc-sections,--no-warn-rwx-segments,--entry=loaderMain \
|
||||||
|
-Wl,--start-group $(LIBS) -Wl,--end-group -T arm7/loader7.ld -nostartfiles
|
||||||
|
|
||||||
|
# Intermediate build files
|
||||||
|
# ------------------------
|
||||||
|
|
||||||
|
OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN)))
|
||||||
|
|
||||||
|
HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN)))
|
||||||
|
|
||||||
|
OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \
|
||||||
|
$(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \
|
||||||
|
$(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP)))
|
||||||
|
|
||||||
|
OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES)
|
||||||
|
|
||||||
|
DEPS := $(OBJS:.o=.d)
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
# -------
|
||||||
|
|
||||||
|
.PHONY: all clean dump
|
||||||
|
|
||||||
|
all: $(BIN)
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@echo " OBJCOPY.7 $@"
|
||||||
|
$(V)$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
$(ELF): $(OBJS)
|
||||||
|
@echo " LD.7 $@"
|
||||||
|
$(V)$(LD) -o $@ $(OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
|
$(DUMP): $(ELF)
|
||||||
|
@echo " OBJDUMP.7 $@"
|
||||||
|
$(V)$(OBJDUMP) -h -C -S $< > $@
|
||||||
|
|
||||||
|
dump: $(DUMP)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo " CLEAN.7"
|
||||||
|
$(V)$(RM) picoLoader7*.bin $(ELF) $(DUMP) $(MAP) $(BUILDDIR)
|
||||||
|
|
||||||
|
# Rules
|
||||||
|
# -----
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.s.o : %.s
|
||||||
|
@echo " AS.7 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.c.o : %.c
|
||||||
|
@echo " CC.7 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.arm.c.o : %.arm.c
|
||||||
|
@echo " CC.7 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.cpp.o : %.cpp
|
||||||
|
@echo " CXX.7 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.arm.cpp.o : %.arm.cpp
|
||||||
|
@echo " CXX.7 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin
|
||||||
|
@echo " BIN2C.7 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c
|
||||||
|
|
||||||
|
# All assets must be built before the source code
|
||||||
|
# -----------------------------------------------
|
||||||
|
|
||||||
|
$(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS)
|
||||||
|
|
||||||
|
# Include dependency files if they exist
|
||||||
|
# --------------------------------------
|
||||||
|
|
||||||
|
-include $(DEPS)
|
||||||
243
Makefile.arm9
Normal file
243
Makefile.arm9
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
# SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||||
|
|
||||||
|
export BLOCKSDS ?= /opt/blocksds/core
|
||||||
|
export BLOCKSDSEXT ?= /opt/blocksds/external
|
||||||
|
|
||||||
|
export LIBTWL ?= $(shell pwd)/libs/libtwl
|
||||||
|
|
||||||
|
export WONDERFUL_TOOLCHAIN ?= /opt/wonderful
|
||||||
|
ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/
|
||||||
|
|
||||||
|
# Source code paths
|
||||||
|
# -----------------
|
||||||
|
|
||||||
|
SOURCEDIRS := arm9/source common
|
||||||
|
INCLUDEDIRS := arm9/source common
|
||||||
|
GFXDIRS :=
|
||||||
|
BINDIRS := arm9/data
|
||||||
|
AUDIODIRS :=
|
||||||
|
|
||||||
|
# Defines passed to all files
|
||||||
|
# ---------------------------
|
||||||
|
|
||||||
|
PLATFORM ?= DSPICO
|
||||||
|
|
||||||
|
DEFINES := -DLIBTWL_ARM9 -DARM9 -DPICO_LOADER_TARGET_$(PLATFORM)
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
# ---------
|
||||||
|
|
||||||
|
LIBS := -ltwl9
|
||||||
|
LIBDIRS := $(BLOCKSDS)/libs/libnds \
|
||||||
|
$(LIBTWL)/libtwl9 $(LIBTWL)/common $(LIBTWL)
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
# ---------------
|
||||||
|
|
||||||
|
NAME := picoLoader9_$(PLATFORM)
|
||||||
|
BUILDDIR := build/$(NAME)
|
||||||
|
BIN := $(NAME).bin
|
||||||
|
ELF := build/$(NAME).elf
|
||||||
|
DUMP := build/$(NAME).dump
|
||||||
|
MAP := build/$(NAME).map
|
||||||
|
SOUNDBANKDIR := $(BUILDDIR)/maxmod
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
# -----
|
||||||
|
|
||||||
|
PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi-
|
||||||
|
CC := $(PREFIX)gcc
|
||||||
|
CXX := $(PREFIX)g++
|
||||||
|
LD := $(PREFIX)gcc
|
||||||
|
OBJCOPY := $(PREFIX)objcopy
|
||||||
|
OBJDUMP := $(PREFIX)objdump
|
||||||
|
MKDIR := mkdir
|
||||||
|
RM := rm -rf
|
||||||
|
|
||||||
|
# Verbose flag
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
ifeq ($(VERBOSE),1)
|
||||||
|
V :=
|
||||||
|
else
|
||||||
|
V := @
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Source files
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
ifneq ($(BINDIRS),)
|
||||||
|
SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin")
|
||||||
|
SOURCES_NFT2 := $(shell find -L $(BINDIRS) -name "*.nft2")
|
||||||
|
INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS))
|
||||||
|
endif
|
||||||
|
ifneq ($(GFXDIRS),)
|
||||||
|
SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png")
|
||||||
|
INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS))
|
||||||
|
endif
|
||||||
|
ifneq ($(AUDIODIRS),)
|
||||||
|
SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)')
|
||||||
|
ifneq ($(SOURCES_AUDIO),)
|
||||||
|
INCLUDEDIRS += $(SOUNDBANKDIR)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s")
|
||||||
|
SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c")
|
||||||
|
SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp")
|
||||||
|
|
||||||
|
# Compiler and linker flags
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
ARCH := -mthumb -mthumb-interwork -mcpu=arm946e-s+nofp
|
||||||
|
|
||||||
|
WARNFLAGS := -Wall
|
||||||
|
|
||||||
|
ifeq ($(SOURCES_CPP),)
|
||||||
|
LIBS += -lc
|
||||||
|
else
|
||||||
|
LIBS += -lstdc++ -lc
|
||||||
|
endif
|
||||||
|
|
||||||
|
INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \
|
||||||
|
$(foreach path,$(LIBDIRS),-I$(path)/include)
|
||||||
|
|
||||||
|
LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib)
|
||||||
|
|
||||||
|
ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \
|
||||||
|
$(ARCH) -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \
|
||||||
|
$(ARCH) -O2 -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
CXXFLAGS += -std=gnu++23 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \
|
||||||
|
$(ARCH) -O2 -ffunction-sections -fdata-sections \
|
||||||
|
-fno-exceptions -fno-rtti \
|
||||||
|
-fno-threadsafe-statics -Wno-volatile \
|
||||||
|
-Wsuggest-override -Werror=suggest-override
|
||||||
|
|
||||||
|
LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) $(DEFINES) -nostartfiles \
|
||||||
|
-Wl,-Map,$(MAP),--gc-sections,--use-blx,--no-warn-rwx-segments,--entry=loaderMain \
|
||||||
|
-Wl,--start-group $(LIBS) -Wl,--end-group -T arm9/loader9.ld
|
||||||
|
|
||||||
|
# Intermediate build files
|
||||||
|
# ------------------------
|
||||||
|
|
||||||
|
OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \
|
||||||
|
$(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_NFT2))) \
|
||||||
|
$(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG)))
|
||||||
|
|
||||||
|
HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \
|
||||||
|
$(patsubst %.nft2,%_nft2.h,$(addprefix $(BUILDDIR)/,$(SOURCES_NFT2))) \
|
||||||
|
$(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG)))
|
||||||
|
|
||||||
|
ifneq ($(SOURCES_AUDIO),)
|
||||||
|
OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o
|
||||||
|
HEADERS_ASSETS += $(SOUNDBANKDIR)/soundbank.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \
|
||||||
|
$(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \
|
||||||
|
$(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP)))
|
||||||
|
|
||||||
|
OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES)
|
||||||
|
|
||||||
|
DEPS := $(OBJS:.o=.d)
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
# -------
|
||||||
|
|
||||||
|
.PHONY: all clean dump
|
||||||
|
|
||||||
|
all: $(BIN)
|
||||||
|
|
||||||
|
$(BIN): $(ELF)
|
||||||
|
@echo " OBJCOPY.9 $@"
|
||||||
|
$(V)$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
$(ELF): $(OBJS)
|
||||||
|
@echo " LD.9 $@"
|
||||||
|
$(V)$(LD) -o $@ $(OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
|
$(DUMP): $(ELF)
|
||||||
|
@echo " OBJDUMP.9 $@"
|
||||||
|
$(V)$(OBJDUMP) -h -C -S $< > $@
|
||||||
|
|
||||||
|
dump: $(DUMP)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo " CLEAN.9"
|
||||||
|
$(V)$(RM) picoLoader9*.bin $(ELF) $(DUMP) $(MAP) $(BUILDDIR)
|
||||||
|
|
||||||
|
# Rules
|
||||||
|
# -----
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.s.o : %.s
|
||||||
|
@echo " AS.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.c.o : %.c
|
||||||
|
@echo " CC.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.arm.c.o : %.arm.c
|
||||||
|
@echo " CC.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.cpp.o : %.cpp
|
||||||
|
@echo " CXX.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.arm.cpp.o : %.arm.cpp
|
||||||
|
@echo " CXX.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin
|
||||||
|
@echo " BIN2C.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.nft2.o $(BUILDDIR)/%_nft2.h : %.nft2
|
||||||
|
@echo " BIN2C.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D)
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.nft2.o $(BUILDDIR)/$*_nft2.c
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit
|
||||||
|
@echo " GRIT.9 $<"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
$(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$*
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c
|
||||||
|
$(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h
|
||||||
|
|
||||||
|
$(SOUNDBANKDIR)/soundbank.h: $(SOURCES_AUDIO)
|
||||||
|
@echo " MMUTIL $^"
|
||||||
|
@$(MKDIR) -p $(@D)
|
||||||
|
@$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \
|
||||||
|
-o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKDIR)/soundbank.h
|
||||||
|
|
||||||
|
$(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKDIR)/soundbank.h
|
||||||
|
@echo " BIN2C soundbank.bin"
|
||||||
|
$(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \
|
||||||
|
$(SOUNDBANKDIR)
|
||||||
|
@echo " CC.9 soundbank_bin.c"
|
||||||
|
$(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \
|
||||||
|
$(SOUNDBANKDIR)/soundbank_bin.c
|
||||||
|
|
||||||
|
# All assets must be built before the source code
|
||||||
|
# -----------------------------------------------
|
||||||
|
|
||||||
|
$(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS)
|
||||||
|
|
||||||
|
# Include dependency files if they exist
|
||||||
|
# --------------------------------------
|
||||||
|
|
||||||
|
-include $(DEPS)
|
||||||
106
README.md
Normal file
106
README.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# Pico Loader
|
||||||
|
Pico Loader is a homebrew and retail DS(i) rom loader supporting a variety of platforms (see below).
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Supports both homebrew and retail DS(i) roms
|
||||||
|
- Supports DSiWare and redirects NAND to the flashcard SD card (acting as "emunand", see below for how to setup)
|
||||||
|
- Supports DS roms with an encrypted secure area if a DS arm7 bios is present at `/_pico/biosnds7.rom`
|
||||||
|
- Supports a wide range of platforms, including popular flashcards and the DSpico
|
||||||
|
- Built-in patches for DS Protect
|
||||||
|
- Fast loading
|
||||||
|
|
||||||
|
Note that Pico Loader can currently not run retail roms from the DSi SD card. Homebrew is supported, however.
|
||||||
|
|
||||||
|
Return to loader is also currently not supported yet.
|
||||||
|
|
||||||
|
## Supported platforms
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> Using the wrong platform could damage your flashcard!
|
||||||
|
|
||||||
|
Note that there can be some game compatibility differences between different platforms.
|
||||||
|
|
||||||
|
| PICO_PLATFORM | Description | DMA |
|
||||||
|
| ------------- | ---------------------------------------------------------------------------------------------- | --- |
|
||||||
|
| ACE3DS | Ace3DS+, Gateway 3DS (blue), r4isdhc.com.cn carts, r4isdhc.hk carts 2020+, various derivatives | ✅ |
|
||||||
|
| AK2 | Acekard 2, 2.1, 2i, r4ids.cn, various derivatives | ❌ |
|
||||||
|
| AKRPG | Acekard RPG SD card | ❌ |
|
||||||
|
| DSPICO | DSpico | ✅ |
|
||||||
|
| DSTT | DSTT, SuperCard DSONE SDHC, r4isdhc.com carts 2014+, r4i-sdhc.com carts, various derivatives | ❌ |
|
||||||
|
| G003 | M3i Zero (GMP-Z003) | ✅ |
|
||||||
|
| ISNITRO | Supports the IS-NITRO-EMULATOR through agb semihosting. | ❌ |
|
||||||
|
| M3DS | M3 DS Real, M3i Zero, iTouchDS, r4rts.com, r4isdhc.com RTS (black) | ❌ |
|
||||||
|
| MELONDS | Melon DS support for testing purposes only. | ❌ |
|
||||||
|
| R4 | Original R4DS (non-SDHC), M3 DS Simply | ❌ |
|
||||||
|
| R4iDSN | r4idsn.com | ❌ |
|
||||||
|
| SUPERCARD | SuperCard (Slot-2 flashcart) | ❌ |
|
||||||
|
|
||||||
|
The DMA column indicates whether DMA card reads are implemented for the platform . Without DMA card reads, some games can have cache related issues.<br>
|
||||||
|
Note that there are still SDK versions and variants for which Pico Loader does not yet support DMA card reads.
|
||||||
|
|
||||||
|
## Setup & Configuration
|
||||||
|
We recommend using WSL (Windows Subsystem for Linux), or MSYS2 to compile this repository.
|
||||||
|
The steps provided will assume you already have one of those environments set up.
|
||||||
|
|
||||||
|
1. Install [BlocksDS](https://blocksds.skylyrac.net/docs/setup/options/)
|
||||||
|
2. Install [.NET 9.0](https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu-install?tabs=dotnet9&pivots=os-linux-ubuntu-2404) for your system (note: this link points to the instructions for Ubuntu, but links for most OS'es are available on the same page)
|
||||||
|
|
||||||
|
## Compiling
|
||||||
|
1. Run `make`
|
||||||
|
- By default this compiles for the DSpico platform. To specify a different platform use `make PICO_PLATFORM=PLATFORM`, for example `make PICO_PLATFORM=R4`. See the table above for the supported platforms.
|
||||||
|
2. To use Pico Loader, create a `_pico` folder in the root of your flashcard SD card and copy the following files to it:
|
||||||
|
- `picoLoader7.bin`
|
||||||
|
- `picoLoader9.bin` (the version for your platform)
|
||||||
|
- `aplist.bin` (generated in the `data` folder of the repo)
|
||||||
|
- `savelist.bin` (generated in the `data` folder of the repo)
|
||||||
|
|
||||||
|
## Emunand
|
||||||
|
When running DSiWare, Pico Loader redirects NAND to the flashcard SD card. This requires the following files and folders, obtained from a DSi nand dump, in the root of your flashcard SD card:
|
||||||
|
- `photo` - The photo partition of nand will be redirected to this folder
|
||||||
|
- `shared1`
|
||||||
|
- `TWLCFG0.dat`
|
||||||
|
- `TWLCFG1.dat`
|
||||||
|
- `shared2`
|
||||||
|
- `launcher`
|
||||||
|
- `wrap.bin`
|
||||||
|
- `sys`
|
||||||
|
- `log`
|
||||||
|
- `product.log`
|
||||||
|
- `shop.log`
|
||||||
|
- `sysmenu.log`
|
||||||
|
- `cert.sys`
|
||||||
|
- `dev.kp`
|
||||||
|
- `HWID.sgn`
|
||||||
|
- `HWINFO_N.dat`
|
||||||
|
- `HWINFO_S.dat`
|
||||||
|
- `TWLFontTable.dat`
|
||||||
|
|
||||||
|
## How to use Pico Loader from homebrew
|
||||||
|
On the arm9:
|
||||||
|
1. Map VRAM blocks A, B, C and D to LCDC
|
||||||
|
2. Load `picoLoader9.bin` to `0x06800000` (VRAM A and B)
|
||||||
|
3. Load `picoLoader7.bin` to `0x06840000` (VRAM C and D)
|
||||||
|
4. Setup the header of picoLoader7 to specify what should be loaded. See `pload_header7_t` in [include/picoLoader7.h](include/picoLoader7.h).
|
||||||
|
- Caution: VRAM does not support byte writes!
|
||||||
|
5. Disable irqs and dma
|
||||||
|
6. Ensure the cache is flushed
|
||||||
|
7. Map VRAM C and D to arm7
|
||||||
|
8. Request the arm7 to boot into picoLoader7
|
||||||
|
- Arm7: Disable sound, irqs and dma and jump to the `entryPoint` specified in the picoLoader7 header. Note that after mapping the VRAM to arm7, it appears at `0x06000000` on the arm7 side.
|
||||||
|
9. Arm9 jump to `0x06800000`
|
||||||
|
|
||||||
|
Note that vram must be executable on the arm9.
|
||||||
|
|
||||||
|
## License
|
||||||
|
This project is licensed under the Zlib license. For details, see `LICENSE.txt`.
|
||||||
|
|
||||||
|
Additional licenses may apply to the project. For details, see the `license` directory.
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
- [@Gericom](https://github.com/Gericom)
|
||||||
|
- [@lifehackerhansol](https://github.com/lifehackerhansol)
|
||||||
|
- [@Dartz150](https://github.com/Dartz150)
|
||||||
|
- [@XLuma](https://github.com/XLuma)
|
||||||
|
- [@edo9300](https://github.com/edo9300)
|
||||||
|
- [@Tcm0](https://github.com/Tcm0)
|
||||||
|
- [@RocketRobz](https://github.com/RocketRobz)
|
||||||
209
arm7/loader7.ld
Normal file
209
arm7/loader7.ld
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
/*--------------------------------------------------------------------------------
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||||
|
v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||||
|
obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
vram : ORIGIN = 0x06000000, LENGTH = 256K
|
||||||
|
}
|
||||||
|
|
||||||
|
__heap_end = ORIGIN(vram) + LENGTH(vram);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.crt0 :
|
||||||
|
{
|
||||||
|
__text_start = . ;
|
||||||
|
KEEP (build/picoLoader7/arm7/source/header.cpp.o(.crt0))
|
||||||
|
KEEP (*(.crt0))
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
.text : /* ALIGN (4): */
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
*(.text.*)
|
||||||
|
*(.stub)
|
||||||
|
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||||
|
*(.gnu.warning)
|
||||||
|
*(.gnu.linkonce.t*)
|
||||||
|
__glue_start = ABSOLUTE(.);
|
||||||
|
*(.glue_7)
|
||||||
|
*(.glue_7t)
|
||||||
|
__glue_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP (*(.fini))
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram =0xff
|
||||||
|
|
||||||
|
__text_end = . ;
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
*all.rodata*(*)
|
||||||
|
*(.roda)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r*)
|
||||||
|
SORT(CONSTRUCTORS)
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >vram
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >vram
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||||
|
could instead move the label definition inside the section, but
|
||||||
|
the linker would then create the section even if it turns out to
|
||||||
|
be empty, which isn't pretty. */
|
||||||
|
. = ALIGN(32 / 8);
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE (__preinit_array_start = .);
|
||||||
|
PROVIDE (__bothinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE (__preinit_array_end = .);
|
||||||
|
|
||||||
|
PROVIDE (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE (__init_array_end = .);
|
||||||
|
PROVIDE (__bothinit_array_end = .);
|
||||||
|
} >vram
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
/* Required by pico-exitprocs.c. */
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
|
PROVIDE (__fini_array_end = .);
|
||||||
|
} >vram
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* gcc uses crtbegin.o to find the start of the constructors, so
|
||||||
|
we make sure it is first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not actually link against
|
||||||
|
crtbegin.o; the linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it doesn't matter which
|
||||||
|
directory crtbegin.o is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
.eh_frame :
|
||||||
|
{
|
||||||
|
KEEP (*(.eh_frame))
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
.gcc_except_table :
|
||||||
|
{
|
||||||
|
*(.gcc_except_table)
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram = 0xff
|
||||||
|
.jcr : { KEEP (*(.jcr)) } >vram = 0
|
||||||
|
|
||||||
|
|
||||||
|
__got_start = . ;
|
||||||
|
.got :
|
||||||
|
{
|
||||||
|
*(.got.plt)
|
||||||
|
*(.got)
|
||||||
|
*(.rel.got)
|
||||||
|
} >vram = 0
|
||||||
|
__got_end = . ;
|
||||||
|
|
||||||
|
|
||||||
|
.data ALIGN(4) : {
|
||||||
|
__data_start = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d*)
|
||||||
|
CONSTRUCTORS
|
||||||
|
. = ALIGN(4);
|
||||||
|
__data_end = ABSOLUTE(.) ;
|
||||||
|
} >vram = 0xff
|
||||||
|
|
||||||
|
__data_end = . ;
|
||||||
|
|
||||||
|
.bss ALIGN(4) :
|
||||||
|
{
|
||||||
|
__bss_start = ABSOLUTE(.);
|
||||||
|
__bss_start__ = ABSOLUTE(.);
|
||||||
|
*(.dynbss)
|
||||||
|
*(.gnu.linkonce.b*)
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||||
|
} >vram
|
||||||
|
|
||||||
|
__bss_end = . ;
|
||||||
|
__bss_end__ = . ;
|
||||||
|
__bss_size = __bss_end - __bss_start;
|
||||||
|
|
||||||
|
__heap_start = . ;
|
||||||
|
|
||||||
|
_end = . ;
|
||||||
|
__end__ = . ;
|
||||||
|
PROVIDE (end = _end);
|
||||||
|
|
||||||
|
/* Stabs debugging sections. */
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
.stab.excl 0 : { *(.stab.excl) }
|
||||||
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||||
|
.stab.index 0 : { *(.stab.index) }
|
||||||
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
/* DWARF debug sections.
|
||||||
|
Symbols in the DWARF debugging sections are relative to the beginning
|
||||||
|
of the section so we begin them at 0. */
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
|
.stack 0x80000 : { _stack = .; *(.stack) }
|
||||||
|
/* These must appear regardless of . */
|
||||||
|
}
|
||||||
3
arm7/source/clearFast.h
Normal file
3
arm7/source/clearFast.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern "C" void clearFast(void* dst, u32 length);
|
||||||
29
arm7/source/clearFast.s
Normal file
29
arm7/source/clearFast.s
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
.text
|
||||||
|
.thumb
|
||||||
|
|
||||||
|
.global clearFast
|
||||||
|
.type clearFast, %function
|
||||||
|
clearFast:
|
||||||
|
push {r4-r7,lr}
|
||||||
|
mov r12, sp
|
||||||
|
mov sp, r0
|
||||||
|
add sp, r1
|
||||||
|
mov r1, #0
|
||||||
|
mov r2, #0
|
||||||
|
mov r3, #0
|
||||||
|
mov r4, #0
|
||||||
|
mov r5, #0
|
||||||
|
mov r6, #0
|
||||||
|
mov r7, #0
|
||||||
|
mov lr, r7
|
||||||
|
1:
|
||||||
|
push {r1-r7,lr}
|
||||||
|
push {r1-r7,lr}
|
||||||
|
cmp sp, r0
|
||||||
|
bne 1b
|
||||||
|
mov sp, r12
|
||||||
|
pop {r4-r7}
|
||||||
|
pop {r3}
|
||||||
|
bx r3
|
||||||
|
|
||||||
|
.end
|
||||||
23
arm7/source/common.h
Normal file
23
arm7/source/common.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <nds/ndstypes.h>
|
||||||
|
#include "fat/ff.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
#include "logger/ILogger.h"
|
||||||
|
|
||||||
|
extern ILogger* gLogger;
|
||||||
|
|
||||||
|
#define MAX_COMPILED_LOG_LEVEL LogLevel::All
|
||||||
|
|
||||||
|
#define LOG_FATAL(...) if (LogLevel::Fatal < MAX_COMPILED_LOG_LEVEL) gLogger->Log(LogLevel::Fatal, __VA_ARGS__)
|
||||||
|
#define LOG_ERROR(...) if (LogLevel::Error < MAX_COMPILED_LOG_LEVEL) gLogger->Log(LogLevel::Error, __VA_ARGS__)
|
||||||
|
#define LOG_WARNING(...) if (LogLevel::Warning < MAX_COMPILED_LOG_LEVEL) gLogger->Log(LogLevel::Warning, __VA_ARGS__)
|
||||||
|
#define LOG_INFO(...) if (LogLevel::Info < MAX_COMPILED_LOG_LEVEL) gLogger->Log(LogLevel::Info, __VA_ARGS__)
|
||||||
|
#define LOG_DEBUG(...) if (LogLevel::Debug < MAX_COMPILED_LOG_LEVEL) gLogger->Log(LogLevel::Debug, __VA_ARGS__)
|
||||||
|
#define LOG_TRACE(...) if (LogLevel::Trace < MAX_COMPILED_LOG_LEVEL) gLogger->Log(LogLevel::Trace, __VA_ARGS__)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern FATFS gFatFs;
|
||||||
61
arm7/source/core/Environment.cpp
Normal file
61
arm7/source/core/Environment.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include <nds.h>
|
||||||
|
#include "picoAgbAdapter.h"
|
||||||
|
#include "Environment.h"
|
||||||
|
|
||||||
|
u32 Environment::_flags;
|
||||||
|
|
||||||
|
static bool detectIsNitroEmulator()
|
||||||
|
{
|
||||||
|
u32 agbMemoryAddress = *(vu32*)0x027FFF7C;
|
||||||
|
if (agbMemoryAddress < 0x08000000 || agbMemoryAddress >= 0x0A000000)
|
||||||
|
return false;
|
||||||
|
// u32 monitorRomLoadAddress = *(vu32*)0x027FFF68;
|
||||||
|
// if (monitorRomLoadAddress < 0x02000000 || monitorRomLoadAddress >= 0x02800000)
|
||||||
|
// return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool detectNocashPrintSuppport()
|
||||||
|
{
|
||||||
|
u32 nocashIdentifier = *(vu32*)0x04FFFA00;
|
||||||
|
return nocashIdentifier == 0x67246F6E; //no$g
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool detectPicoAgbAdapter()
|
||||||
|
{
|
||||||
|
REG_EXMEMSTAT &= ~0xFF;
|
||||||
|
return PICO_AGB_IDENTIFIER == PICO_AGB_IDENTIFIER_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::Initialize(bool dsiMode)
|
||||||
|
{
|
||||||
|
_flags = ENVIRONMENT_FLAGS_NONE;
|
||||||
|
if (dsiMode)
|
||||||
|
{
|
||||||
|
_flags |= ENVIRONMENT_FLAGS_DSI_MODE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (detectIsNitroEmulator())
|
||||||
|
{
|
||||||
|
_flags |= ENVIRONMENT_FLAGS_IS_NITRO_EMULATOR;
|
||||||
|
_flags |= ENVIRONMENT_FLAGS_JTAG_SEMIHOSTING;
|
||||||
|
|
||||||
|
REG_EXMEMSTAT &= ~0xFF;
|
||||||
|
|
||||||
|
u32 agbMemoryAddress = *(vu32*)0x027FFF7C;
|
||||||
|
if (*(vu32*)(agbMemoryAddress + 0x100) == 0x44495349) //ISID
|
||||||
|
_flags |= ENVIRONMENT_FLAGS_AGB_SEMIHOSTING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (detectPicoAgbAdapter())
|
||||||
|
_flags |= ENVIRONMENT_FLAGS_PICO_AGB_ADAPTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(_flags & ENVIRONMENT_FLAGS_IS_NITRO_EMULATOR))
|
||||||
|
{
|
||||||
|
if (detectNocashPrintSuppport())
|
||||||
|
_flags |= ENVIRONMENT_FLAGS_NOCASH_PRINT;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
arm7/source/core/Environment.h
Normal file
32
arm7/source/core/Environment.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Environment
|
||||||
|
{
|
||||||
|
enum EnvironmentFlags : u32
|
||||||
|
{
|
||||||
|
ENVIRONMENT_FLAGS_NONE = 0,
|
||||||
|
|
||||||
|
ENVIRONMENT_FLAGS_DSI_MODE = (1 << 0),
|
||||||
|
ENVIRONMENT_FLAGS_NOCASH_PRINT = (1 << 1),
|
||||||
|
ENVIRONMENT_FLAGS_IS_NITRO_EMULATOR = (1 << 2),
|
||||||
|
ENVIRONMENT_FLAGS_JTAG_SEMIHOSTING = (1 << 3),
|
||||||
|
ENVIRONMENT_FLAGS_AGB_SEMIHOSTING = (1 << 4),
|
||||||
|
ENVIRONMENT_FLAGS_DLDI = (1 << 5),
|
||||||
|
ENVIRONMENT_FLAGS_ARGV = (1 << 6),
|
||||||
|
ENVIRONMENT_FLAGS_PICO_AGB_ADAPTER = (1 << 7)
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 _flags;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Initialize(bool dsiMode);
|
||||||
|
|
||||||
|
static inline bool IsDsiMode() { return _flags & ENVIRONMENT_FLAGS_DSI_MODE; }
|
||||||
|
static inline bool SupportsNocashPrint() { return _flags & ENVIRONMENT_FLAGS_NOCASH_PRINT; }
|
||||||
|
static inline bool IsIsNitroEmulator() { return _flags & ENVIRONMENT_FLAGS_IS_NITRO_EMULATOR; }
|
||||||
|
static inline bool SupportsJtagSemihosting() { return _flags & ENVIRONMENT_FLAGS_JTAG_SEMIHOSTING; }
|
||||||
|
static inline bool SupportsAgbSemihosting() { return _flags & ENVIRONMENT_FLAGS_AGB_SEMIHOSTING; }
|
||||||
|
static inline bool SupportsDldi() { return _flags & ENVIRONMENT_FLAGS_DLDI; }
|
||||||
|
static inline bool SupportsArgv() { return _flags & ENVIRONMENT_FLAGS_ARGV; }
|
||||||
|
static inline bool HasPicoAgbAdapter() { return _flags & ENVIRONMENT_FLAGS_PICO_AGB_ADAPTER; }
|
||||||
|
};
|
||||||
26
arm7/source/crt0.s
Normal file
26
arm7/source/crt0.s
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.section ".crt0", "ax"
|
||||||
|
.arm
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
.type _start, %function
|
||||||
|
_start:
|
||||||
|
// disable irqs
|
||||||
|
ldr r0,= 0x04000208
|
||||||
|
strb r0, [r0]
|
||||||
|
// clear bss
|
||||||
|
ldr r0,= __bss_start
|
||||||
|
ldr r1,= __bss_end
|
||||||
|
cmp r0, r1
|
||||||
|
beq bss_done
|
||||||
|
mov r2, #0
|
||||||
|
1:
|
||||||
|
str r2, [r0], #4
|
||||||
|
cmp r0, r1
|
||||||
|
bne 1b
|
||||||
|
bss_done:
|
||||||
|
ldr sp,= 0x0380FD80
|
||||||
|
b loaderMain
|
||||||
|
|
||||||
|
.pool
|
||||||
|
|
||||||
|
.end
|
||||||
17
arm7/source/errorDisplay/ErrorDisplay.cpp
Normal file
17
arm7/source/errorDisplay/ErrorDisplay.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <libtwl/i2c/i2cMcu.h>
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "ipcCommands.h"
|
||||||
|
#include "core/mini-printf.h"
|
||||||
|
#include "ErrorDisplay.h"
|
||||||
|
|
||||||
|
void ErrorDisplay::PrintError(const char* errorFormat, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
va_start(va, errorFormat);
|
||||||
|
mini_vsnprintf((char*)0x02000000, 1024, errorFormat, va);
|
||||||
|
sendToArm9(IPC_COMMAND_ARM9_DISPLAY_ERROR);
|
||||||
|
va_end(va);
|
||||||
|
while (true);
|
||||||
|
}
|
||||||
11
arm7/source/errorDisplay/ErrorDisplay.h
Normal file
11
arm7/source/errorDisplay/ErrorDisplay.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// @brief Class for displaying critical errors on screen.
|
||||||
|
class ErrorDisplay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// @brief Formats and sends a critical error message to the arm9 to display it on screen.
|
||||||
|
/// @note This function does not return.
|
||||||
|
/// @param errorFormat The error message to format.
|
||||||
|
void PrintError(const char* errorFormat, ...);
|
||||||
|
};
|
||||||
205
arm7/source/fat/diskio.cpp
Normal file
205
arm7/source/fat/diskio.cpp
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* If a working storage control module is available, it should be */
|
||||||
|
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||||
|
/* This is an example of glue functions to attach various exsisting */
|
||||||
|
/* storage control modules to the FatFs module with a defined API. */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <nds/ndstypes.h>
|
||||||
|
#include <nds/disc_io.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libtwl/rtos/rtosIrq.h>
|
||||||
|
#include "core/Environment.h"
|
||||||
|
// #include <libtwl/rtos/rtosIrq.h>
|
||||||
|
// #include <libtwl/rtos/rtosEvent.h>
|
||||||
|
#include "ff.h" /* Obtains integer types */
|
||||||
|
#include "diskio.h" /* Declarations of disk functions */
|
||||||
|
#include "dldi.h"
|
||||||
|
#include "../mmc/sdmmc.h"
|
||||||
|
// #include "core/semihosting.h"
|
||||||
|
|
||||||
|
/* Definitions of physical drive number for each drive */
|
||||||
|
#define DEV_FAT 0 //dldi
|
||||||
|
#define DEV_SD 1 //dsi sd
|
||||||
|
#define DEV_PC 2 //image on pc via semihosting
|
||||||
|
#define DEV_PC2 3 //image on pc via agb semihosting
|
||||||
|
|
||||||
|
// static int sPcFileHandle;
|
||||||
|
// static rtos_event_t sSemihostingCommandDoneEvent;
|
||||||
|
|
||||||
|
//extern "C" int sdmmc_sd_startup();
|
||||||
|
// extern FN_MEDIUM_STARTUP _DLDI_startup_ptr;
|
||||||
|
// extern FN_MEDIUM_READSECTORS _DLDI_readSectors_ptr;
|
||||||
|
// extern FN_MEDIUM_WRITESECTORS _DLDI_writeSectors_ptr;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Get Drive Status */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern "C" DSTATUS disk_status (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void gbaIrq(u32 mask)
|
||||||
|
// {
|
||||||
|
// rtos_signalEvent(&sSemihostingCommandDoneEvent);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Inidialize a Drive */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern "C" DSTATUS disk_initialize (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == DEV_FAT)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (Environment::IsDsiMode() && pdrv == DEV_SD)
|
||||||
|
{
|
||||||
|
pico_SDMMC_init(SDMMC_DEV_CARD);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (pdrv == DEV_PC)
|
||||||
|
{
|
||||||
|
// sPcFileHandle = sh_openFile("d:\\Emulators\\No$Debugger 3.0\\DSI-1.SD", SH_OPEN_MODE_R_PLUS_B);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (pdrv == DEV_PC2)
|
||||||
|
{
|
||||||
|
// rtos_createEvent(&sSemihostingCommandDoneEvent);
|
||||||
|
// rtos_disableIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
// rtos_ackIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
// rtos_setIrqFunc(RTOS_IRQ_GBA_IREQ, gbaIrq);
|
||||||
|
// rtos_enableIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Read Sector(s) */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_read (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
BYTE *buff, /* Data buffer to store read data */
|
||||||
|
DWORD sector, /* Start sector in LBA */
|
||||||
|
UINT count /* Number of sectors to read */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == DEV_FAT)
|
||||||
|
{
|
||||||
|
dldi_readSectors(buff, sector, count);
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
else if (Environment::IsDsiMode() && pdrv == DEV_SD)
|
||||||
|
{
|
||||||
|
pico_SDMMC_readSectors(SDMMC_DEV_CARD, sector, buff, count);
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
else if (pdrv == DEV_PC)
|
||||||
|
{
|
||||||
|
// sh_seekFile(sPcFileHandle, sector * 512);
|
||||||
|
// sh_readFile(sPcFileHandle, buff, count * 512);
|
||||||
|
// return RES_OK;
|
||||||
|
}
|
||||||
|
else if (pdrv == DEV_PC2)
|
||||||
|
{
|
||||||
|
// rtos_clearEvent(&sSemihostingCommandDoneEvent);
|
||||||
|
u32 agbMem = *(u32*)0x027FFF7C;
|
||||||
|
*(vu16*)(agbMem + 0x10002) = 1;
|
||||||
|
*(vu32*)(agbMem + 0x10004) = sector;
|
||||||
|
*(vu32*)(agbMem + 0x10008) = count;
|
||||||
|
rtos_disableIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
rtos_ackIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
*(vu16*)(agbMem + 0x10000) = 0x55;
|
||||||
|
while (!(rtos_getIrqFlags() & RTOS_IRQ_GBA_IREQ));
|
||||||
|
// rtos_waitEvent(&sSemihostingCommandDoneEvent, false, true);
|
||||||
|
if (*(vu16*)(agbMem + 0x10000) != 0xAA)
|
||||||
|
return RES_ERROR;
|
||||||
|
memcpy(buff, (const void*)(agbMem + 0x10020), count * 512);
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Write Sector(s) */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if FF_FS_READONLY == 0
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_write (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
const BYTE *buff, /* Data to be written */
|
||||||
|
DWORD sector, /* Start sector in LBA */
|
||||||
|
UINT count /* Number of sectors to write */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == DEV_FAT)
|
||||||
|
{
|
||||||
|
dldi_writeSectors(buff, sector, count);
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
else if (Environment::IsDsiMode() && pdrv == DEV_SD)
|
||||||
|
{
|
||||||
|
pico_SDMMC_writeSectors(SDMMC_DEV_CARD, sector, buff, count);
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
else if (pdrv == DEV_PC)
|
||||||
|
{
|
||||||
|
// sh_seekFile(sPcFileHandle, sector * 512);
|
||||||
|
// sh_writeFile(sPcFileHandle, buff, count * 512);
|
||||||
|
// return RES_OK;
|
||||||
|
}
|
||||||
|
else if (pdrv == DEV_PC2)
|
||||||
|
{
|
||||||
|
// rtos_clearEvent(&sSemihostingCommandDoneEvent);
|
||||||
|
u32 agbMem = *(u32*)0x027FFF7C;
|
||||||
|
memcpy((void*)(agbMem + 0x10020), buff, count * 512);
|
||||||
|
*(vu16*)(agbMem + 0x10002) = 2;
|
||||||
|
*(vu32*)(agbMem + 0x10004) = sector;
|
||||||
|
*(vu32*)(agbMem + 0x10008) = count;
|
||||||
|
rtos_disableIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
rtos_ackIrqMask(RTOS_IRQ_GBA_IREQ);
|
||||||
|
*(vu16*)(agbMem + 0x10000) = 0x55;
|
||||||
|
while (!(rtos_getIrqFlags() & RTOS_IRQ_GBA_IREQ));
|
||||||
|
// rtos_waitEvent(&sSemihostingCommandDoneEvent, false, true);
|
||||||
|
if (*(vu16*)(agbMem + 0x10000) != 0xAA)
|
||||||
|
return RES_ERROR;
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Miscellaneous Functions */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_ioctl (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||||
|
BYTE cmd, /* Control code */
|
||||||
|
void *buff /* Buffer to send/receive control data */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
77
arm7/source/fat/diskio.h
Normal file
77
arm7/source/fat/diskio.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*-----------------------------------------------------------------------/
|
||||||
|
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||||
|
/-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _DISKIO_DEFINED
|
||||||
|
#define _DISKIO_DEFINED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Status of Disk Functions */
|
||||||
|
typedef BYTE DSTATUS;
|
||||||
|
|
||||||
|
/* Results of Disk Functions */
|
||||||
|
typedef enum {
|
||||||
|
RES_OK = 0, /* 0: Successful */
|
||||||
|
RES_ERROR, /* 1: R/W Error */
|
||||||
|
RES_WRPRT, /* 2: Write Protected */
|
||||||
|
RES_NOTRDY, /* 3: Not Ready */
|
||||||
|
RES_PARERR /* 4: Invalid Parameter */
|
||||||
|
} DRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------*/
|
||||||
|
/* Prototypes for disk control functions */
|
||||||
|
|
||||||
|
|
||||||
|
DSTATUS disk_initialize (BYTE pdrv);
|
||||||
|
DSTATUS disk_status (BYTE pdrv);
|
||||||
|
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||||
|
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||||
|
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||||
|
|
||||||
|
|
||||||
|
/* Disk Status Bits (DSTATUS) */
|
||||||
|
|
||||||
|
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||||
|
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||||
|
#define STA_PROTECT 0x04 /* Write protected */
|
||||||
|
|
||||||
|
|
||||||
|
/* Command code for disk_ioctrl fucntion */
|
||||||
|
|
||||||
|
/* Generic command (Used by FatFs) */
|
||||||
|
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||||
|
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||||
|
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||||
|
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||||
|
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||||
|
|
||||||
|
/* Generic command (Not used by FatFs) */
|
||||||
|
#define CTRL_POWER 5 /* Get/Set power status */
|
||||||
|
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||||
|
#define CTRL_EJECT 7 /* Eject media */
|
||||||
|
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||||
|
|
||||||
|
/* MMC/SDC specific ioctl command */
|
||||||
|
#define MMC_GET_TYPE 10 /* Get card type */
|
||||||
|
#define MMC_GET_CSD 11 /* Get CSD */
|
||||||
|
#define MMC_GET_CID 12 /* Get CID */
|
||||||
|
#define MMC_GET_OCR 13 /* Get OCR */
|
||||||
|
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||||
|
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||||
|
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||||
|
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||||
|
|
||||||
|
/* ATA/CF specific ioctl command */
|
||||||
|
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||||
|
#define ATA_GET_MODEL 21 /* Get model name */
|
||||||
|
#define ATA_GET_SN 22 /* Get serial number */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user