-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sg3d: Initial implementation for the Stargate 3DS
Fork of ace3ds_sd. Key differences: - No XOR at end of write flush command - Scrambler does not start during write buffer transfer
- Loading branch information
1 parent
cac4988
commit b9e62d0
Showing
5 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#--------------------------------------------------------------------------------- | ||
.SUFFIXES: | ||
#--------------------------------------------------------------------------------- | ||
|
||
ifeq ($(strip $(DEVKITARM)),) | ||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM") | ||
endif | ||
|
||
include $(DEVKITARM)/ds_rules | ||
|
||
#--------------------------------------------------------------------------------- | ||
# TARGET is the name of the output | ||
# BUILD is the directory where object files & intermediate files will be placed | ||
# SOURCES is a list of directories containing source code | ||
# DATA is a list of directories containing data files | ||
# INCLUDES is a list of directories containing header files | ||
# SPECS is the directory containing the important build and link files | ||
#--------------------------------------------------------------------------------- | ||
export TARGET := $(shell basename $(CURDIR)) | ||
BUILD := build | ||
SOURCES := source ../../common_source | ||
DATA := data | ||
INCLUDES := include ../../common_source | ||
|
||
|
||
#--------------------------------------------------------------------------------- | ||
# options for code generation | ||
#--------------------------------------------------------------------------------- | ||
ARCH := -mthumb-interwork | ||
|
||
CFLAGS := -g -Wall -O2\ | ||
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\ | ||
-ffast-math -ffreestanding \ | ||
$(ARCH) | ||
|
||
CFLAGS += $(INCLUDE) -DARM7 -fPIC | ||
|
||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions | ||
|
||
ASFLAGS := -g $(ARCH) $(INCLUDE) | ||
LDFLAGS = -nostartfiles -nostdlib -T dldi.ld -g $(ARCH) -Wl,-Map,$(TARGET).map,--gc-sections -ffunction-sections -fdata-sections | ||
|
||
LIBS := | ||
|
||
#--------------------------------------------------------------------------------- | ||
# list of directories containing libraries, this must be the top level containing | ||
# include and lib | ||
#--------------------------------------------------------------------------------- | ||
LIBDIRS := $(LIBNDS) | ||
|
||
|
||
#--------------------------------------------------------------------------------- | ||
# no real need to edit anything past this point unless you need to add additional | ||
# rules for different file extensions | ||
#--------------------------------------------------------------------------------- | ||
ifneq ($(BUILD),$(notdir $(CURDIR))) | ||
#--------------------------------------------------------------------------------- | ||
|
||
export OUTPUT := $(CURDIR)/$(TARGET) | ||
|
||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ | ||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) | ||
|
||
export DEPSDIR := $(CURDIR)/$(BUILD) | ||
|
||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) | ||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) | ||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) | ||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) | ||
|
||
#--------------------------------------------------------------------------------- | ||
# use CXX for linking C++ projects, CC for standard C | ||
#--------------------------------------------------------------------------------- | ||
ifeq ($(strip $(CPPFILES)),) | ||
#--------------------------------------------------------------------------------- | ||
export LD := $(CC) | ||
#--------------------------------------------------------------------------------- | ||
else | ||
#--------------------------------------------------------------------------------- | ||
export LD := $(CXX) | ||
#--------------------------------------------------------------------------------- | ||
endif | ||
#--------------------------------------------------------------------------------- | ||
|
||
export OFILES := $(addsuffix .o,$(BINFILES)) \ | ||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) | ||
|
||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ | ||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \ | ||
-I$(CURDIR)/$(BUILD) | ||
|
||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) | ||
|
||
.PHONY: $(BUILD) clean all | ||
|
||
#--------------------------------------------------------------------------------- | ||
all: $(BUILD) | ||
|
||
$(BUILD): | ||
@[ -d $@ ] || mkdir -p $@ | ||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile | ||
|
||
#--------------------------------------------------------------------------------- | ||
clean: | ||
@echo clean ... | ||
@rm -fr $(BUILD) $(TARGET).dldi $(TARGET).elf | ||
|
||
|
||
#--------------------------------------------------------------------------------- | ||
else | ||
|
||
DEPENDS := $(OFILES:.o=.d) | ||
|
||
#--------------------------------------------------------------------------------- | ||
# main targets | ||
#--------------------------------------------------------------------------------- | ||
$(OUTPUT).dldi : $(OUTPUT).elf | ||
$(OUTPUT).elf : $(OFILES) | ||
|
||
|
||
#--------------------------------------------------------------------------------- | ||
%.dldi: %.elf | ||
@$(OBJCOPY) -O binary $< $@ | ||
@echo built ... $(notdir $@) | ||
|
||
|
||
-include $(DEPENDS) | ||
|
||
|
||
#--------------------------------------------------------------------------------------- | ||
endif | ||
#--------------------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// SPDX-License-Identifier: Zlib | ||
// | ||
// Copyright (C) 2006-2016 Michael Chisholm (Chishm) | ||
// Copyright (C) 2006-2016 Dave Murphy (WinterMute) | ||
|
||
#include <nds/arm9/dldi_asm.h> | ||
|
||
.section ".crt0","ax" | ||
.global _start | ||
.align 4 | ||
.arm | ||
|
||
@ Driver patch file standard header -- 16 bytes | ||
|
||
.word 0xBF8DA5ED @ Magic number to identify this region | ||
.asciz " Chishm" @ Identifying Magic string (8 bytes with null terminator) | ||
.byte 0x01 @ Version number | ||
.byte DLDI_SIZE_4KB @ Log [base-2] of the size of this driver in bytes. | ||
.byte FIX_GOT | FIX_BSS | FIX_GLUE @ Sections to fix | ||
.byte 0x00 @ Space allocated in the application, leave empty. | ||
|
||
@ Text identifier - can be anything up to 47 chars + terminating null -- 48 bytes | ||
|
||
.align 4 | ||
.asciz "Stargate 3DS" | ||
|
||
@ Offsets to important sections within the data -- 32 bytes | ||
|
||
.align 6 | ||
.word __text_start @ data start | ||
.word __data_end @ data end | ||
.word __glue_start @ Interworking glue start -- Needs address fixing | ||
.word __glue_end @ Interworking glue end | ||
.word __got_start @ GOT start -- Needs address fixing | ||
.word __got_end @ GOT end | ||
.word __bss_start @ bss start -- Needs setting to zero | ||
.word __bss_end @ bss end | ||
|
||
@ IO_INTERFACE data -- 32 bytes | ||
|
||
.ascii "SG3D" | ||
.word FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_NDS | ||
.word startup @ Function pointers to standard device driver functions | ||
.word is_inserted | ||
.word read_sectors | ||
.word write_sectors | ||
.word clear_status | ||
.word shutdown | ||
|
||
_start: | ||
|
||
.align | ||
.pool | ||
.end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
Stargate 3DS | ||
Card IO routines | ||
Copyright (C) 2023 lifehackerhansol | ||
SPDX-License-Identifier: Zlib | ||
*/ | ||
|
||
#include <nds/ndstypes.h> | ||
#include "io_sg3d.h" | ||
#include "libtwl_card.h" | ||
|
||
static inline void SG3D_ReadCardData(u64 command, u32 flags, void *buffer, u32 length) | ||
{ | ||
card_romSetCmd(command); | ||
card_romStartXfer(flags, false); | ||
if ((u32)buffer & 3) | ||
card_romCpuReadUnaligned((u8 *)buffer, length); | ||
else | ||
card_romCpuRead(buffer, length); | ||
} | ||
|
||
static inline void SG3D_WriteCardData(u64 command, u32 flags, const void *buffer, u32 length) | ||
{ | ||
card_romSetCmd(command); | ||
card_romStartXfer(flags, false); | ||
if ((u32)buffer & 3) | ||
card_romCpuWriteUnaligned((u8 *)buffer, length); | ||
else | ||
card_romCpuWrite(buffer, length); | ||
} | ||
|
||
static inline u32 SG3D_SendCommand(const u64 command) | ||
{ | ||
card_romSetCmd(command); | ||
card_romStartXfer(SG3D_CTRL_READ_4B, false); | ||
card_romWaitDataReady(); | ||
return card_romGetData(); | ||
} | ||
|
||
void SG3D_SDReadSector(u32 sector, void *buffer) | ||
{ | ||
// wait until data is ready | ||
// request should return 0 when ready to access | ||
while(SG3D_SendCommand(SG3D_CMD_SD_READ_REQUEST(sector))); | ||
|
||
SG3D_ReadCardData(SG3D_CMD_SD_READ_DATA, SG3D_CTRL_READ_512B, buffer, 128); | ||
} | ||
|
||
void SG3D_SDWriteSector(u32 sector, const void *buffer) | ||
{ | ||
SG3D_WriteCardData(SG3D_CMD_SD_WRITE_START(sector), SG3D_CTRL_WRITE_512B, buffer, 128); | ||
|
||
// Wait until write finishes | ||
// status should return 0 when done | ||
while(SG3D_SendCommand(SG3D_CMD_SD_WRITE_STAT(sector))); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
Stargate 3DS | ||
Card IO routines | ||
Copyright (C) 2023 lifehackerhansol | ||
SPDX-License-Identifier: Zlib | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <nds/ndstypes.h> | ||
|
||
#ifndef NULL | ||
#define NULL 0 | ||
#endif | ||
|
||
// Stargate 3DS defines | ||
// Stargate 3DS MCCNT1 flags | ||
#define SG3D_CTRL_BASE (MCCNT1_ENABLE | MCCNT1_RESET_OFF | MCCNT1_CMD_SCRAMBLE | MCCNT1_LATENCY2(0) | MCCNT1_LATENCY1(0)) | ||
#define SG3D_CTRL_READ_4B (SG3D_CTRL_BASE | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_LEN_4) | ||
#define SG3D_CTRL_READ_512B (SG3D_CTRL_BASE | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_LEN_512) | ||
#define SG3D_CTRL_WRITE_512B (SG3D_CTRL_BASE | MCCNT1_DIR_WRITE | MCCNT1_LEN_512) | ||
|
||
// Stargate 3DS MCCMDs | ||
#define SG3D_CMD_SD_READ_DATA (0xBAull << 56) | ||
|
||
static inline u64 SG3D_CMD_SD_READ_REQUEST(u32 sector) | ||
{ | ||
return (0xB9ull << 56) | ((u64)sector << 24); | ||
} | ||
|
||
static inline u64 SG3D_CMD_SD_WRITE_START(u32 sector) | ||
{ | ||
return (0xBBull << 56) | ((u64)sector << 24); | ||
} | ||
|
||
static inline u64 SG3D_CMD_SD_WRITE_STAT(u32 sector) | ||
{ | ||
u64 command = (0xBCull << 56) | ((u64)sector << 24); | ||
return command; | ||
} | ||
|
||
// user API | ||
void SG3D_SDReadSector(u32 sector, void* buffer); | ||
void SG3D_SDWriteSector(u32 sector, const void* buffer); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier: CC0-1.0 | ||
// | ||
// SPDX-FileContributor: Antonio Niño Díaz, 2023 | ||
// SPDX-FileContributor: lifehackerhansol, 2023 | ||
|
||
#include <nds/ndstypes.h> | ||
|
||
#include "io_sg3d.h" | ||
#include "libtwl_card.h" | ||
|
||
// Initialize the driver. Returns true on success. | ||
bool startup(void) | ||
{ | ||
return true; | ||
} | ||
|
||
// Returns true if a card is present and initialized. | ||
bool is_inserted(void) | ||
{ | ||
return true; | ||
} | ||
|
||
// Reads 512 byte sectors into a buffer that may be unaligned. Returns true on | ||
// success. | ||
bool read_sectors(uint32_t sector, uint32_t num_sectors, void *buffer) | ||
{ | ||
for (int i = 0; i < num_sectors; i++) | ||
{ | ||
SG3D_SDReadSector((sector + i), buffer); | ||
buffer = (u8 *)buffer + 0x200; | ||
} | ||
return true; | ||
} | ||
|
||
// Writes 512 byte sectors from a buffer that may be unaligned. Returns true on | ||
// success. | ||
bool write_sectors(uint32_t sector, uint32_t num_sectors, const void *buffer) | ||
{ | ||
for (int i = 0; i < num_sectors; i++) | ||
{ | ||
SG3D_SDWriteSector((sector + i), buffer); | ||
buffer = (u8 *)buffer + 0x200; | ||
} | ||
return true; | ||
} | ||
|
||
// Clear error flags from the card. Returns true on success. | ||
bool clear_status(void) | ||
{ | ||
return true; | ||
} | ||
|
||
// Shutdowns the card. This may never be called. | ||
bool shutdown(void) | ||
{ | ||
return true; | ||
} |