mirror of
https://github.com/ApacheThunder/nrioSaveTester.git
synced 2025-06-18 11:15:38 -04:00
Initial Commit
* Initial read/write test of SRAM implemented.
This commit is contained in:
parent
43be916e74
commit
86f5dab921
54
.gitignore
vendored
Normal file
54
.gitignore
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# devkitARM/libnds/3DS compiled stuff
|
||||
*.tmd
|
||||
*.cia
|
||||
*.cmd
|
||||
*.nds
|
||||
*.app
|
||||
*.tmd
|
||||
*.zip
|
||||
*.arm7
|
||||
*.arm9
|
||||
*.elf
|
||||
build
|
||||
data
|
||||
|
||||
# Stuff used to build custom banner/misc other things that shouldn't be in repo.
|
||||
*.dldi
|
||||
*.zip
|
||||
|
||||
# Stuff generated by Windows.
|
||||
Thumbs.db
|
||||
desktop.ini
|
50
Makefile
Normal file
50
Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
export TARGET := nrioSaveTester
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
# specify a directory which contains the nitro filesystem
|
||||
# this is relative to the Makefile
|
||||
NITRO_FILES :=
|
||||
|
||||
include $(DEVKITARM)/ds_rules
|
||||
|
||||
.PHONY: checkarm7 checkarm9 clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all: checkarm7 checkarm9 $(TARGET).nds
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
checkarm7:
|
||||
$(MAKE) -C arm7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
checkarm9:
|
||||
$(MAKE) -C arm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET).nds : $(NITRO_FILES) arm7/$(TARGET).elf arm9/$(TARGET).elf
|
||||
ndstool -c $(TARGET).nds -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
|
||||
-h 0x200 -t banner.bin \
|
||||
$(_ADDFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm7/$(TARGET).elf:
|
||||
$(MAKE) -C arm7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/$(TARGET).elf:
|
||||
$(MAKE) -C arm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
$(MAKE) -C arm9 clean
|
||||
$(MAKE) -C arm7 clean
|
||||
rm -f $(TARGET).nds $(TARGET).arm7 $(TARGET).arm9
|
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# NRIO Save Tester: N-Card Save Test Tool
|
||||
|
||||
Simple program to test SRAM on N-Cards to make sure battery is still good.
|
||||
|
||||
|
||||
Note. Program may hang on initial boot with fresh save file. If this occurs, just reboot and once XMENU generates a save file, it should operate normally.
|
||||
|
||||
On initial boot. Use B button to write test save to SRAM. Once down follow prompt to exit and power down. Leave powered off for a minute, an hour, a day...however long you desire to test.
|
||||
|
||||
A good battery should hold a save for at least a day. Though techinically if it holds a save longer then a few minutes you could reasonably get by if you remember to reboot quickly to backup save.
|
||||
|
||||
Program will show what the expected CRCs should be and what the CRC's the save tile returned and will indicate accordingly if they do not match.
|
||||
|
126
arm7/Makefile
Normal file
126
arm7/Makefile
Normal file
@ -0,0 +1,126 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/ds_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
# DATA is a list of directories containing binary files
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
INCLUDES := include build
|
||||
DATA :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb-interwork
|
||||
|
||||
CFLAGS := -g -Wall -O2 \
|
||||
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer \
|
||||
-ffast-math \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM7
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-rtti
|
||||
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,--nmagic -Wl,-Map,$(notdir $*).map
|
||||
|
||||
LIBS := -lnds7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 ARM7ELF := $(CURDIR)/$(TARGET).elf
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
|
||||
|
||||
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)/*.*)))
|
||||
|
||||
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)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
.PHONY: $(BUILD) clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) *.elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(ARM7ELF) : $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
66
arm7/source/main.c
Normal file
66
arm7/source/main.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
default ARM7 core
|
||||
|
||||
Copyright (C) 2005 - 2010
|
||||
Michael Noland (joat)
|
||||
Jason Rogers (dovoto)
|
||||
Dave Murphy (WinterMute)
|
||||
|
||||
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.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
#include <nds.h>
|
||||
|
||||
volatile bool exitflag = false;
|
||||
|
||||
void VblankHandler(void) { }
|
||||
void VcountHandler() { inputGetAndSend(); }
|
||||
void powerButtonCB() { exitflag = true; }
|
||||
|
||||
int main() {
|
||||
readUserSettings();
|
||||
ledBlink(0);
|
||||
|
||||
irqInit();
|
||||
// Start the RTC tracking IRQ
|
||||
initClockIRQ();
|
||||
fifoInit();
|
||||
touchInit();
|
||||
|
||||
SetYtrigger(80);
|
||||
|
||||
installSystemFIFO();
|
||||
|
||||
irqSet(IRQ_VCOUNT, VcountHandler);
|
||||
irqSet(IRQ_VBLANK, VblankHandler);
|
||||
|
||||
irqEnable(IRQ_VBLANK | IRQ_VCOUNT);
|
||||
|
||||
setPowerButtonCB(powerButtonCB);
|
||||
|
||||
// Keep the ARM7 mostly idle
|
||||
while (!exitflag) {
|
||||
if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R)))exitflag = true;
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
138
arm9/Makefile
Normal file
138
arm9/Makefile
Normal file
@ -0,0 +1,138 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/ds_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
# DATA is a list of directories containing binary files embedded using bin2o
|
||||
# GRAPHICS is a list of directories containing image files to be converted with grit
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
BUILD := build
|
||||
SOURCES := source include
|
||||
INCLUDES := include
|
||||
DATA := ../data
|
||||
GRAPHICS := fonts
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb -mthumb-interwork -march=armv5te -mtune=arm946e-s
|
||||
|
||||
CFLAGS := -g -Wall -Os \
|
||||
$(ARCH) $(INCLUDE) -DARM9
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lnds9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(LIBNDS) $(PORTLIBS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 ARM9ELF := $(CURDIR)/$(TARGET).elf
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(GRAPHICS),$(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)))
|
||||
BMPFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.bmp)))
|
||||
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_BIN := $(addsuffix .o,$(BINFILES))
|
||||
|
||||
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export OFILES := $(BMPFILES:.bmp=.o) $(OFILES_BIN) $(OFILES_SOURCES)
|
||||
|
||||
export HFILES := $(BMPFILES:.bmp=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(ARM9ELF) : $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# This rule creates assembly source files using grit
|
||||
# grit takes an image file and a .grit describing how the file is to be processed
|
||||
# add additional rules like this for each image extension
|
||||
# you use in the graphics folders
|
||||
#---------------------------------------------------------------------------------
|
||||
%.s %.h: %.bmp %.grit
|
||||
#---------------------------------------------------------------------------------
|
||||
grit $< -fts -o$*
|
||||
|
||||
-include $(DEPSDIR)/*.d
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
BIN
arm9/fonts/font.bmp
Normal file
BIN
arm9/fonts/font.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
25
arm9/fonts/font.grit
Normal file
25
arm9/fonts/font.grit
Normal file
@ -0,0 +1,25 @@
|
||||
#-------------------------------------------------------
|
||||
# graphics in tile format
|
||||
#-------------------------------------------------------
|
||||
-gt
|
||||
|
||||
#-------------------------------------------------------
|
||||
# output first 16 colors of the palette
|
||||
#-------------------------------------------------------
|
||||
-pw16
|
||||
|
||||
#-------------------------------------------------------
|
||||
# no tile reduction
|
||||
#-------------------------------------------------------
|
||||
-mR!
|
||||
|
||||
#-------------------------------------------------------
|
||||
# no map output
|
||||
#-------------------------------------------------------
|
||||
-m!
|
||||
|
||||
#-------------------------------------------------------
|
||||
# graphics bit depth is 4 (16 color)
|
||||
#-------------------------------------------------------
|
||||
-gB4
|
||||
|
540
arm9/include/cardme.cpp
Normal file
540
arm9/include/cardme.cpp
Normal file
@ -0,0 +1,540 @@
|
||||
/*
|
||||
see:CARDME.H
|
||||
*/
|
||||
|
||||
#include <nds/card.h>
|
||||
|
||||
#include "cardme.h"
|
||||
|
||||
// #define CARDME_CR1 (*(vuint16*)0x040001A0) /*fixed*/
|
||||
// #define CARDME_EEPDATA (*(vuint16*)0x040001A2) /*fixed*/
|
||||
// #define EepromWaitBusy() while (REG_AUXSPICNT & /*BUSY*/0x80);
|
||||
|
||||
void EepromWaitBusy() {
|
||||
while (REG_AUXSPICNT & /*BUSY*/0x80);
|
||||
}
|
||||
|
||||
// void cardmeReadEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
|
||||
// void cardmeWriteEepromT1(u32 address, u8 *apData, u32 aLength, u32 addrtype);
|
||||
// void cardmeWriteEepromT2(u32 address, u8 *apData, u32 aLength, u32 addrtype);
|
||||
// void cardmeWriteEepromT3(u32 address, u8 *apData, u32 aLength, u32 addrtype);
|
||||
|
||||
// #define WAIT_CR REG_EXMEMCNT
|
||||
|
||||
/***********************
|
||||
void cardmeReadHeader(uint8 * header) {
|
||||
//---------------------------------------------------------------------------------
|
||||
cardRead00(0, (uint32 *)header, 512, 0xA93F1FFF);
|
||||
}
|
||||
**********************/
|
||||
|
||||
u8 cardmeCMD(u8 cmd,int address) {
|
||||
// int address=i & 1;
|
||||
u8 ret;
|
||||
int k;
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
|
||||
REG_AUXSPICNT = 0xFFFF;
|
||||
REG_AUXSPIDATA = cmd; //
|
||||
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
for(k=0;k<256;k++) {
|
||||
ret = REG_AUXSPIDATA;
|
||||
if(ret!=0xFF)break;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
u8 cardmeReadID(int i) {
|
||||
int address=i & 1;
|
||||
u8 ret;
|
||||
int k;
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
|
||||
REG_AUXSPICNT = 0xFFFF;
|
||||
REG_AUXSPIDATA = 0xAB; // READ ID
|
||||
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
for(k=0;k<16;k++) {
|
||||
ret = REG_AUXSPIDATA;
|
||||
if(ret!=0xFF)break;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern int cardmeSizeT2(void);
|
||||
|
||||
int cardmeGetType(void) {
|
||||
// u8 ret;
|
||||
u8 c00;
|
||||
u8 c05;
|
||||
u8 c9f;
|
||||
// u8 c03;
|
||||
|
||||
REG_EXMEMCNT &= ~0x0880; // DS Card access ARM9:bit11=0 GBA Cart access ARM9:bit7=0
|
||||
// c03=cardmeCMD(0x03,0);
|
||||
cardmeCMD(0x03,0);
|
||||
c05=cardmeCMD(0x05,0);
|
||||
c9f=cardmeCMD(0x9f,0);
|
||||
c00=cardmeCMD(0x00,0);
|
||||
// if((c00==0x00) && (c9f==0x00))return 0; // PassMe? 判別不可
|
||||
if((c00==0x00) && (c9f==0x00))return 1; // PassMe? 判別不可
|
||||
// if((c00==0xff) && (c05==0xff) && (c9f==0xff))return -1;
|
||||
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0xF0 && (c9f==0xff))return 1;
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0xff))return 2;
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x00))return 3;
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x12))return 3; // NEW TYPE 3
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x13))return 3; // NEW TYPE 3+ 4Mbit
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x14))return 3; // NEW TYPE 3+ 8Mbit
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x16))return 3; // NEW TYPE 3+ 32Mbit
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x84 && (c9f==0x17))return 3; // NEW TYPE 3+ 64Mbit
|
||||
|
||||
// /* 判定不可 */
|
||||
if(cardmeSizeT2() != 0)return 2;
|
||||
// return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cardmeSizeT3(void) {
|
||||
u8 c9f;
|
||||
c9f=cardmeCMD(0x9f,0);
|
||||
|
||||
if(c9f==0x17) { // NEW TYPE 3+ 64Mbit(8192MByte)
|
||||
return 8192*1024; // NEW TYPE 3+ 8Mbit(1024KByte)
|
||||
}
|
||||
if(c9f==0x14) { // NEW TYPE 3+ 8Mbit(1024MByte)
|
||||
return 1024*1024; // NEW TYPE 3+ 8Mbit(1024KByte)
|
||||
}
|
||||
if(c9f==0x13) { // NEW TYPE 3+ 4Mbit(512MByte)
|
||||
return 512*1024; // NEW TYPE 3+ 4Mbit(512KByte)
|
||||
}
|
||||
return 256*1024; // TYPE 3 2Mbit(256KByte)
|
||||
}
|
||||
|
||||
|
||||
#define OFOT0 (8*1024-1) // 8KBの末端
|
||||
#define OFOT1 (2*8*1024-1) // 16KBの末端
|
||||
int cardmeSizeT2(void) {
|
||||
int tp=2;
|
||||
|
||||
u8 buf1[1]; // +0k data read -> write
|
||||
u8 buf2[1]; // +8k data read -> read
|
||||
u8 buf3[1]; // +0k ~data write
|
||||
u8 buf4[1]; // +8k data new comp buf2
|
||||
|
||||
cardmeReadEeprom(OFOT0,buf1,1,tp);
|
||||
cardmeReadEeprom(OFOT1,buf2,1,tp);
|
||||
buf3[0]=~buf2[0];
|
||||
|
||||
cardmeWriteEeprom(OFOT0,buf3,1,tp);
|
||||
cardmeReadEeprom(OFOT0,buf4,1,tp);
|
||||
cardmeWriteEeprom(OFOT0,buf1,1,tp);
|
||||
if(buf4[0]!=buf3[0])return 0; // Not type 2
|
||||
|
||||
cardmeReadEeprom(OFOT1,buf4,1,tp);
|
||||
|
||||
// +8kも書き換わっている
|
||||
if(buf4[0]!=buf2[0])return 8*1024; // 8KB(64kbit)
|
||||
|
||||
return 64*1024; // 64KB(512kbit)
|
||||
}
|
||||
|
||||
int cardmeSize(int tp) {
|
||||
if(-1 <= tp && tp <= 3) {
|
||||
// -1 0 1 2 3
|
||||
// int eepsz[5]={ 0,8192, 512, 8192, 256*1024};
|
||||
int eepsz[5]={ 0,8192, 512, 64*1024, 256*1024};
|
||||
|
||||
if((tp==2) || (tp==0))return cardmeSizeT2();
|
||||
|
||||
if(tp==3)return cardmeSizeT3();
|
||||
tp++;
|
||||
return eepsz[tp];
|
||||
}
|
||||
// return 0;
|
||||
return 512;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void cardmeReadEeprom(u32 address, u8 *data, u32 length, u32 addrtype) {
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
// REG_AUXSPICNT = 0xFFFF;
|
||||
REG_AUXSPIDATA = 0x03 | ((addrtype == 1) ? address>>8<<3 : 0);
|
||||
EepromWaitBusy();
|
||||
|
||||
if (addrtype == 3) {
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
if (addrtype >= 2) {
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
REG_AUXSPIDATA = (address) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
while (length > 0) {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
*data++ = REG_AUXSPIDATA;
|
||||
length--;
|
||||
}
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define T1BLOCKSZ (16)
|
||||
// TYPE1 4kbit EEPROM
|
||||
void cardmeWriteEepromT1(u32 address, u8 *apData, u32 aLength, u32 addrtype) {
|
||||
int i;
|
||||
u32 last=address+aLength;
|
||||
|
||||
while (address < last) {
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// program maximum of 16 bytes
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
// WRITE COMMAND 0x02 + A8 << 3
|
||||
REG_AUXSPIDATA = 0x02 | (address & BIT(8)) >> (8-3) ;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
|
||||
for (i = 0; address < last && i < T1BLOCKSZ; i++, address++) {
|
||||
REG_AUXSPIDATA = *apData;
|
||||
EepromWaitBusy();
|
||||
apData++;
|
||||
}
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TYPE2 64kbit EEPROM
|
||||
void cardmeWriteEepromT2(u32 address, u8 *apData, u32 aLength, u32 addrtype) {
|
||||
int i;
|
||||
u32 last=address+aLength;
|
||||
|
||||
while (address < last) {
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// program maximum of 32 bytes
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x02;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address >> 8;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
|
||||
for (i = 0; address < last && i < 32; i++, address++) {
|
||||
REG_AUXSPIDATA = *apData;
|
||||
EepromWaitBusy();
|
||||
apData++;
|
||||
}
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define T3BLOCKSZ (256)
|
||||
// TYPE3 2Mbit FLASH MEMORY
|
||||
void cardmeWriteEepromT3(u32 address, u8 *apData, u32 aLength, u32 addrtype) {
|
||||
int i;
|
||||
u32 last=address+aLength;
|
||||
|
||||
while (address < last) {
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// program maximum of 32 bytes
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x02;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
|
||||
for (i = 0; address < last && i < T3BLOCKSZ; i++, address++) {
|
||||
REG_AUXSPIDATA = *apData;
|
||||
EepromWaitBusy();
|
||||
apData++;
|
||||
}
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Chip Erase NEW : clear FLASH MEMORY (TYPE 3 ONLY)
|
||||
int cardmeChipErase(void) {
|
||||
int sz;
|
||||
void cardmeSectorErase(u32 address);
|
||||
sz= cardmeSizeT3();
|
||||
|
||||
cardmeSectorErase(0x00000);
|
||||
cardmeSectorErase(0x10000);
|
||||
cardmeSectorErase(0x20000);
|
||||
cardmeSectorErase(0x30000);
|
||||
if(sz==512*1024) {
|
||||
cardmeSectorErase(0x40000);
|
||||
cardmeSectorErase(0x50000);
|
||||
cardmeSectorErase(0x60000);
|
||||
cardmeSectorErase(0x70000);
|
||||
}
|
||||
if(sz==1024*1024) {
|
||||
cardmeSectorErase(0x80000);
|
||||
cardmeSectorErase(0x90000);
|
||||
cardmeSectorErase(0xA0000);
|
||||
cardmeSectorErase(0xB0000);
|
||||
cardmeSectorErase(0xC0000);
|
||||
cardmeSectorErase(0xD0000);
|
||||
cardmeSectorErase(0xE0000);
|
||||
cardmeSectorErase(0xF0000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// COMMAND Sec.erase 0xD8
|
||||
void cardmeSectorErase(u32 address) {
|
||||
// int i;
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// SectorErase 0xD8
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0xD8;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait erase to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
// EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
|
||||
/*void cardmeSectorUnlock(u32 address) {
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = 0x8000 | 0x2000 | 0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = 0x40;
|
||||
|
||||
// Individual block unlock command for PUYA flash chip P25Q32SH used in EZP
|
||||
REG_AUXSPICNT = 0x8000 | 0x2000 | 0x40;
|
||||
REG_AUXSPIDATA = 0x39;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = 0x40;
|
||||
|
||||
// wait erase to finish
|
||||
REG_AUXSPICNT = 0x8000 | 0x2000 | 0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
REG_AUXSPICNT = 0x40;
|
||||
}
|
||||
|
||||
void cardmeChipUnlock() {
|
||||
REG_AUXSPICNT = 0x8000 | 0x2000 | 0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = 0x40;
|
||||
|
||||
// Global unlock command for PUYA flash chip P25Q32SH used in EZP
|
||||
REG_AUXSPICNT = 0x8000 | 0x2000 | 0x40;
|
||||
REG_AUXSPIDATA = 0x98;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = 0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = 0x8000 | 0x2000 | 0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = 0x40;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
// Chip Erase : clear FLASH MEMORY (TYPE 3 ONLY)
|
||||
// COMMAND 0xC7
|
||||
int cardmeChipErase_old(void) {
|
||||
// {
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// Chip Erase 0xC7
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0xC7;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do {
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void cardmeWriteEeprom(u32 address, u8 *apData, u32 aLength, u32 addrtype) {
|
||||
switch(addrtype) {
|
||||
case 1: {
|
||||
cardmeWriteEepromT1(address,apData,aLength,addrtype);
|
||||
return;
|
||||
}break;
|
||||
case 2: {
|
||||
cardmeWriteEepromT2(address,apData,aLength,addrtype);
|
||||
return;
|
||||
}break;
|
||||
case 3: {
|
||||
cardmeWriteEepromT3(address,apData,aLength,addrtype);
|
||||
return;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
52
arm9/include/cardme.h
Normal file
52
arm9/include/cardme.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
cardme by SaTa. for Public Domain
|
||||
2005/10/30
|
||||
NEW TYPE 2 ASPJ has 512kbit(64Kbyte)EEPROM
|
||||
2005/10/21
|
||||
NEW TYPE 3
|
||||
cardmeChipErase use cardmeSectorErase
|
||||
*/
|
||||
#ifndef CARDME_HEADER_FIX_NDSLIB_HELP__WATASI_MOMOI_SUKIDESU_YOROSIKU
|
||||
#define CARDME_HEADER_FIX_NDSLIB_HELP__WATASI_MOMOI_SUKIDESU_YOROSIKU
|
||||
|
||||
#include <nds.h>
|
||||
#include <string.h>
|
||||
//#include "dbg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cardmeReadEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
|
||||
int cardmeChipErase(void); // USE TO TYPE 3 FLASH MEMORY ONLY
|
||||
|
||||
void cardmeSectorErase(u32 address);
|
||||
|
||||
|
||||
int cardmeGetType(void); //
|
||||
/*
|
||||
-1:no card or no EEPROM
|
||||
0:unknown PassMe?
|
||||
1:TYPE 1 4Kbit(512Byte) EEPROM
|
||||
2:TYPE 2 64Kbit(8KByte)or 512kbit(64Kbyte) EEPROM
|
||||
3:TYPE 3 2Mbit(256KByte) FLASH MEMORY
|
||||
*/
|
||||
int cardmeSize(int tp);
|
||||
/*
|
||||
tp:1~3
|
||||
return:size (byte)
|
||||
*/
|
||||
u8 cardmeReadID(int i) ; // don't work ??
|
||||
u8 cardmeCMD(u8 cmd,int address) ;
|
||||
|
||||
/*void cardmeSectorUnlock(u32 address);
|
||||
void cardmeChipUnlock(void);*/
|
||||
void cardmeReadHeader(uint8 * header);
|
||||
void cardmeWriteEeprom(u32 address, u8 *data, u32 length, u32 addrtype);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //CARDME_HEADER_FIX_NDSLIB_HELP__WATASI_MOMOI_SUKIDESU_YOROSIKU
|
||||
|
88
arm9/include/crc32.h
Normal file
88
arm9/include/crc32.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
static const u32 crc32tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
|
||||
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
||||
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
|
||||
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
||||
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
|
||||
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
||||
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
|
||||
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
|
||||
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
|
||||
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
||||
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
||||
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
|
||||
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
|
||||
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
|
||||
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
||||
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
|
||||
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
||||
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
|
||||
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
||||
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
|
||||
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
|
||||
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
||||
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
|
||||
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
||||
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
|
||||
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
||||
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
|
||||
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
|
||||
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
|
||||
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
||||
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
||||
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
|
||||
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
|
||||
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
|
||||
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
||||
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
|
||||
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
||||
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
|
||||
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
||||
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
|
||||
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
|
||||
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
||||
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
|
||||
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
||||
};
|
||||
|
||||
u32 crc32(unsigned char *buf, u32 size) {
|
||||
u32 i, crc;
|
||||
crc = 0xFFFFFFFF;
|
||||
for (i = 0; i < size; i++)crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
|
||||
return crc^0xFFFFFFFF;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
BIN
arm9/include/saveBinary.bin
Normal file
BIN
arm9/include/saveBinary.bin
Normal file
Binary file not shown.
6
arm9/include/saveBinary.s
Normal file
6
arm9/include/saveBinary.s
Normal file
@ -0,0 +1,6 @@
|
||||
.arm
|
||||
.global saveBinary, saveBinaryEnd
|
||||
|
||||
saveBinary: .incbin "../include/saveBinary.bin"
|
||||
saveBinaryEnd:
|
||||
|
136
arm9/include/tonccpy.c
Normal file
136
arm9/include/tonccpy.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "tonccpy.h"
|
||||
//# tonccpy.c
|
||||
|
||||
//! VRAM-safe cpy.
|
||||
/*! This version mimics memcpy in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memcpy, but faster
|
||||
implementations can be made.
|
||||
\param dst Destination pointer.
|
||||
\param src Source pointer.
|
||||
\param size Fill-length in bytes.
|
||||
\note The pointers and size need not be word-aligned.
|
||||
*/
|
||||
void tonccpy(void *dst, const void *src, uint size)
|
||||
{
|
||||
if(size==0 || dst==0 || src==0)
|
||||
return;
|
||||
|
||||
uint count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if( ((u32)src|(u32)dst)%4==0 && size>=4)
|
||||
{
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if(size == 0)
|
||||
return;
|
||||
|
||||
src8= (u8*)src32;
|
||||
dst16= (u16*)dst32;
|
||||
}
|
||||
else // Unaligned.
|
||||
{
|
||||
uint dstOfs= (u32)dst&1;
|
||||
src8= (u8*)src;
|
||||
dst16= (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if(dstOfs != 0)
|
||||
{
|
||||
*dst16= (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if(--size==0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count= size/2;
|
||||
while(count--)
|
||||
{
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if(size&1)
|
||||
*dst16= (*dst16 &~ 0xFF) | *src8;
|
||||
}
|
||||
//# toncset.c
|
||||
|
||||
//! VRAM-safe memset, internal routine.
|
||||
/*! This version mimics memset in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memset.
|
||||
\param dst Destination pointer.
|
||||
\param fill Word to fill with.
|
||||
\param size Fill-length in bytes.
|
||||
\note The \a dst pointer and \a size need not be
|
||||
word-aligned. In the case of unaligned fills, \a fill
|
||||
will be masked off to match the situation.
|
||||
*/
|
||||
void __toncset(void *dst, u32 fill, uint size)
|
||||
{
|
||||
if(size==0 || dst==0)
|
||||
return;
|
||||
|
||||
uint left= (u32)dst&3;
|
||||
u32 *dst32= (u32*)(dst-left);
|
||||
u32 count, mask;
|
||||
|
||||
// Unaligned head.
|
||||
if(left != 0)
|
||||
{
|
||||
// Adjust for very small stint.
|
||||
if(left+size<4)
|
||||
{
|
||||
mask= BIT_MASK(size*8)<<(left*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
mask= BIT_MASK(left*8);
|
||||
*dst32= (*dst32 & mask) | (fill&~mask);
|
||||
dst32++;
|
||||
size -= 4-left;
|
||||
}
|
||||
|
||||
// Main stint.
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
switch(tmp) {
|
||||
do { *dst32++ = fill;
|
||||
case 3: *dst32++ = fill;
|
||||
case 2: *dst32++ = fill;
|
||||
case 1: *dst32++ = fill;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Tail
|
||||
size &= 3;
|
||||
if(size)
|
||||
{
|
||||
mask= BIT_MASK(size*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
}
|
||||
}
|
43
arm9/include/tonccpy.h
Normal file
43
arm9/include/tonccpy.h
Normal file
@ -0,0 +1,43 @@
|
||||
//# Stuff you may not have yet.
|
||||
|
||||
#ifndef TONCCPY_H
|
||||
#define TONCCPY_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
#define BIT_MASK(len) ( (1<<(len))-1 )
|
||||
static inline u32 quad8(u16 x) { x |= x<<8; return x | x<<16; }
|
||||
|
||||
|
||||
//# Declarations and inlines.
|
||||
|
||||
void tonccpy(void *dst, const void *src, uint size);
|
||||
|
||||
void __toncset(void *dst, u32 fill, uint size);
|
||||
static inline void toncset(void *dst, u8 src, uint size);
|
||||
static inline void toncset16(void *dst, u16 src, uint size);
|
||||
static inline void toncset32(void *dst, u32 src, uint size);
|
||||
|
||||
|
||||
//! VRAM-safe memset, byte version. Size in bytes.
|
||||
static inline void toncset(void *dst, u8 src, uint size)
|
||||
{ __toncset(dst, quad8(src), size); }
|
||||
|
||||
//! VRAM-safe memset, halfword version. Size in hwords.
|
||||
static inline void toncset16(void *dst, u16 src, uint size)
|
||||
{ __toncset(dst, src|src<<16, size*2); }
|
||||
|
||||
//! VRAM-safe memset, word version. Size in words.
|
||||
static inline void toncset32(void *dst, u32 src, uint size)
|
||||
{ __toncset(dst, src, size*4); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
156
arm9/source/main.cpp
Normal file
156
arm9/source/main.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
#include <nds.h>
|
||||
#include <stdio.h>
|
||||
#include <nds/arm9/console.h>
|
||||
|
||||
#include "font.h"
|
||||
#include "tonccpy.h"
|
||||
#include "crc32.h"
|
||||
#include "cardme.h"
|
||||
|
||||
#define programSav 0x02000000
|
||||
#define saveBuff 0x02000200
|
||||
// #define saveTest 0x02000300
|
||||
|
||||
typedef struct sProgSAVStruct {
|
||||
u8 padding[240];
|
||||
u32 savCRC32;
|
||||
u16 savCRC16;
|
||||
u8 padding2[10];
|
||||
u8 saveBinary[256];
|
||||
} tProgSAVStruct;
|
||||
|
||||
|
||||
volatile tProgSAVStruct* ProgSave;
|
||||
volatile tProgSAVStruct* TestSave;
|
||||
|
||||
static PrintConsole tpConsole;
|
||||
static PrintConsole btConsole;
|
||||
|
||||
extern PrintConsole* currentConsole;
|
||||
|
||||
static int bg;
|
||||
static int bgSub;
|
||||
|
||||
const char* textBuffer = "X------------------------------X\nX------------------------------X";
|
||||
|
||||
volatile bool UpdateProgressText = false;
|
||||
volatile bool PrintWithStat = false;
|
||||
volatile bool ClearOnUpdate = true;
|
||||
volatile int savetype = 0;
|
||||
volatile u32 savesize = 0;
|
||||
|
||||
extern u8 saveBinary[512];
|
||||
|
||||
// DTCM_DATA u8 savebuf[512];
|
||||
// DTCM_DATA u8 testbuf[256];
|
||||
|
||||
|
||||
bool ReadOrWritePrompt() {
|
||||
printf("\n Press [A] to test current save.");
|
||||
printf("\n\n Press [B] to write new save\n and exit.\n");
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
switch (keysDown()) {
|
||||
case KEY_A:
|
||||
consoleClear();
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
if (keysUp())return true;
|
||||
}
|
||||
break;
|
||||
case KEY_B: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ExitPrompt(bool isError) {
|
||||
if (isError) {
|
||||
printf("\n Failed to detect a valid\n save chip.\n");
|
||||
} else {
|
||||
printf("\n Finished save operations.\n");
|
||||
}
|
||||
printf("\n\n Press [A] to exit.\n");
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
switch (keysDown()) {
|
||||
case KEY_A: return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CustomConsoleInit() {
|
||||
videoSetMode(MODE_0_2D);
|
||||
videoSetModeSub(MODE_0_2D);
|
||||
vramSetBankA (VRAM_A_MAIN_BG);
|
||||
vramSetBankC (VRAM_C_SUB_BG);
|
||||
|
||||
bg = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 1, 0);
|
||||
bgSub = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 1, 0);
|
||||
|
||||
consoleInit(&btConsole, 3, BgType_Text4bpp, BgSize_T_256x256, 20, 0, false, false);
|
||||
consoleInit(&tpConsole, 3, BgType_Text4bpp, BgSize_T_256x256, 20, 0, true, false);
|
||||
|
||||
ConsoleFont font;
|
||||
font.gfx = (u16*)fontTiles;
|
||||
font.pal = (u16*)fontPal;
|
||||
font.numChars = 95;
|
||||
font.numColors = fontPalLen / 2;
|
||||
font.bpp = 4;
|
||||
font.asciiOffset = 32;
|
||||
font.convertSingleColor = true;
|
||||
consoleSetFont(&btConsole, &font);
|
||||
consoleSetFont(&tpConsole, &font);
|
||||
|
||||
consoleSelect(&tpConsole);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
defaultExceptionHandler();
|
||||
CustomConsoleInit();
|
||||
sysSetCartOwner(true);
|
||||
printf("\n\n\n\n\n\n\n\n\n\n\n N-CARD SAVE BATTERY TESTER");
|
||||
consoleSelect(&btConsole);
|
||||
|
||||
savetype = cardmeGetType();
|
||||
|
||||
if(savetype > 0)savesize = cardmeSize(savetype);
|
||||
|
||||
if ((savesize > 0) && (savetype > 0)) {
|
||||
memset((u8*)saveBuff, 0xFF, 512);
|
||||
memset((u8*)programSav, 0xFF, 512);
|
||||
tonccpy((u8*)programSav, saveBinary, 512);
|
||||
ProgSave = (tProgSAVStruct*)programSav;
|
||||
|
||||
if (ReadOrWritePrompt()) {
|
||||
consoleClear();
|
||||
// cardReadEeprom(0, (u8*)saveBuff, 512, savetype);
|
||||
cardmeReadEeprom(0, (u8*)saveBuff, 512, savetype);
|
||||
TestSave = (tProgSAVStruct*)saveBuff;
|
||||
|
||||
u16 get_crc16 = swiCRC16(0xFFFF, (void*)TestSave->saveBinary, 0x100);
|
||||
u32 get_crc32 = crc32((unsigned char*)TestSave->saveBinary, 0x100);
|
||||
|
||||
iprintf(" Expected CRC16: %2X\n", (unsigned int)ProgSave->savCRC16);
|
||||
iprintf(" Expected CRC32: %4X\n\n", (unsigned int)ProgSave->savCRC32);
|
||||
iprintf(" Got save CRC16: %2X\n", (unsigned int)get_crc16);
|
||||
iprintf(" Got save CRC32: %4X\n\n", (unsigned int)get_crc32);
|
||||
|
||||
if ((ProgSave->savCRC16 != get_crc16) || (ProgSave->savCRC32 != get_crc32)) {
|
||||
if (ProgSave->savCRC16 != get_crc16)printf(" CRC16 mismatch!\n");
|
||||
if (ProgSave->savCRC32 != get_crc32)printf(" CRC32 mismatch!\n\n");
|
||||
printf(" Battery may need changing!");
|
||||
}
|
||||
} else {
|
||||
if(savetype == 3)cardmeSectorErase(0);
|
||||
cardmeWriteEeprom(0, (u8*)programSav, 512, savetype);
|
||||
}
|
||||
} else {
|
||||
return ExitPrompt(true);
|
||||
}
|
||||
return ExitPrompt(false);
|
||||
}
|
||||
|
BIN
banner.bin
Normal file
BIN
banner.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user