Initial Commit: v0.186
This commit is contained in:
commit
bb1e653309
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
## Build files
|
||||
*.v64
|
||||
*.elf
|
||||
*.o
|
||||
*.bin
|
||||
*.dfs
|
||||
|
||||
## OSX junk
|
||||
.DS_Store
|
||||
.Trashes
|
||||
._*
|
||||
|
||||
## Temporary files
|
||||
*.tmp
|
||||
*~
|
32
ALT64.INI
Normal file
32
ALT64.INI
Normal file
@ -0,0 +1,32 @@
|
||||
; alt64 config file
|
||||
|
||||
[ed64] ; Menu config
|
||||
build=18 ; Release build nr
|
||||
border_color_1=FFFFFFFF ; 0x00000080 RGBT
|
||||
border_color_2=3F3F3FFF ; 0x3F3F3FFF RGBT 00000060 w light
|
||||
box_color=000000B6 ; 0x00000080 RGBT
|
||||
selection_color=80008070 ; 80008070 RGBT 6495ED60
|
||||
list_font_color=CDC9C940 ; 80008070 RGBT 6495ED60
|
||||
list_dir_font_color=FFFFE040 ; 80008070 RGBT 6495ED60
|
||||
selection_font_color=FFB90FFF ; 80008070 RGBT 6495ED60
|
||||
text_offset=0 ; shift menu horizontal e.g. -1
|
||||
cd_behaviour=1 ; 0=first entry 1=last entry
|
||||
scroll_behaviour=0 ; 0=page-system 1=classic
|
||||
quick_boot=1 ; 'START' boots last rom
|
||||
sound_on=1 ; sounds 1=on 0=off
|
||||
page_display=1 ; display page
|
||||
tv_mode=1 ; 1=ntsc 2=pal 3=mpal 0=force_off
|
||||
enable_colored_list=1 ; 1=enable 0=disalbe
|
||||
ext_type=0 ; 0=classic 1=OS64
|
||||
sd_speed=2 ; 1=25MHz 2=50MHz
|
||||
background_image=background.png ; backgrund png image 320x240 32bit
|
||||
hide_sysfolder=0 ; 1=hide 0=don't hide
|
||||
mempak_path=/MEMPAKS/ ; surround with slashes
|
||||
save_path=SDSAVE ; save directory inside ED64
|
||||
|
||||
[user]
|
||||
name = saturnu ; Username
|
||||
|
||||
[gblite]
|
||||
save_path=/ED64/SDSAVE/ ; save directory surround with slashes
|
||||
tv_mode=0 ; 1=ntsc 2=pal 3=mpal 0=force_off
|
38
Makefile
Normal file
38
Makefile
Normal file
@ -0,0 +1,38 @@
|
||||
ROOTDIR = $(N64_INST)
|
||||
GCCN64PREFIX = $(ROOTDIR)/bin/mips64-elf-
|
||||
CHKSUM64PATH = $(ROOTDIR)/bin/chksum64
|
||||
MKDFSPATH = $(ROOTDIR)/bin/mkdfs
|
||||
HEADERPATH = $(ROOTDIR)/lib
|
||||
N64TOOL = $(ROOTDIR)/bin/n64tool
|
||||
HEADERNAME = header
|
||||
|
||||
|
||||
LINK_FLAGS = -G4 -L$(ROOTDIR)/toolchain_font/lib -L$(ROOTDIR)/mips64-elf/lib -ldragon -L$(ROOTDIR)/toolchain_font/lib -lmikmod -lmad -lc -lm -ldragonsys -lnosys $(LIBS) -Tn64ld.x
|
||||
PROG_NAME = menu
|
||||
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -G4 -I$(ROOTDIR)/toolchain_font/include -I$(ROOTDIR)/mips64-elf/include -lpthread -lrt -D_REENTRANT -DUSE_TRUETYPE
|
||||
ASFLAGS = -mtune=vr4300 -march=vr4300
|
||||
CC = $(GCCN64PREFIX)gcc
|
||||
AS = $(GCCN64PREFIX)as
|
||||
LD = $(GCCN64PREFIX)ld
|
||||
OBJCOPY = $(GCCN64PREFIX)objcopy
|
||||
OBJS = $(PROG_NAME).o everdrive.o fat.o disk.o mem.o sys.o ini.o strlib.o utils.o sram.o stb_image.o chksum64.o mp3.o
|
||||
|
||||
$(PROG_NAME).v64: $(PROG_NAME).elf test.dfs
|
||||
$(OBJCOPY) $(PROG_NAME).elf $(PROG_NAME).bin -O binary
|
||||
rm -f $(PROG_NAME).v64
|
||||
$(N64TOOL) -l 4M -t "EverDrive OS" -h ./header.ed64 -o OS64.v64 $(PROG_NAME).bin -s 1M test.dfs
|
||||
$(CHKSUM64PATH) OS64.v64
|
||||
|
||||
$(PROG_NAME).elf : $(OBJS)
|
||||
$(LD) -o $(PROG_NAME).elf $(OBJS) $(LINK_FLAGS)
|
||||
|
||||
copy: $(PROG_NAME).v64
|
||||
sh upload.sh
|
||||
|
||||
test.dfs:
|
||||
$(MKDFSPATH) test.dfs ./filesystem/
|
||||
|
||||
all: $(PROG_NAME).v64
|
||||
|
||||
clean:
|
||||
rm -f *.v64 *.elf *.o *.bin *.dfs
|
56
README
Normal file
56
README
Normal file
@ -0,0 +1,56 @@
|
||||
alt64
|
||||
=====
|
||||
|
||||
alternative everdrive64 menu
|
||||
|
||||
|
||||
Kuroneko!
|
||||
|
||||
:\ /; _
|
||||
; \___/ ; ; ;
|
||||
,:-"' `"-:. / ;
|
||||
_ /,---. ,---.\ _ _; /
|
||||
_:>(( | ) ( | ))<:_ ,-""_,"
|
||||
\````` `````/""""",-""
|
||||
'-.._ v _..-' )
|
||||
/ ___ ____,.. \
|
||||
/ / | | | ( \. \
|
||||
ctr / / | | | | \ \
|
||||
`" `" `" `"
|
||||
|
||||
nyannyannyannyannyannyannyannyannyannyannyannyannyannyannyannyannyan
|
||||
|
||||
|
||||
hello here is my menu for the everdrive64.
|
||||
if you don't have one you should visit krikzzs homepage
|
||||
for ordering information. ^^
|
||||
|
||||
if you want to build the menu, you need a n64 toolchain
|
||||
you can get one free from
|
||||
|
||||
http://www.dragonminded.com/n64dev/libdragon/
|
||||
https://github.com/DragonMinded/libdragon
|
||||
|
||||
i used the libmikmod linked on his site too for the menu
|
||||
http://www.dragonminded.com/n64dev/libmikmod-3.2.0-beta2.tgz
|
||||
|
||||
|
||||
if you are on linux, try out the build script
|
||||
https://github.com/DragonMinded/libdragon/tree/master/tools/build
|
||||
|
||||
here are a few setting hints
|
||||
export INSTALL_PATH=/usr/mips64-elf
|
||||
set this to your home directory if you don't have root access
|
||||
|
||||
i was in need to alter the cxxflags to G0 to lowercase
|
||||
CXXFLAGS="-g0 -O2"
|
||||
|
||||
it's a good idea to the latest versions for the toolchain
|
||||
export BINUTILS_V=2.23.52
|
||||
export GCC_V=4.8.0
|
||||
export NEWLIB_V=1.20.0
|
||||
|
||||
|
||||
optional:
|
||||
get libn64-hkz to get more into flashram savegames
|
||||
http://sourceforge.net/projects/n64dev/
|
106
chksum64.c
Normal file
106
chksum64.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
checksum rom in psram, based on
|
||||
|
||||
chksum64 V1.2, a program to calculate the ROM checksum of Nintendo64 ROMs.
|
||||
Copyright (C) 1997 Andreas Sterbenz (stan@sbox.tu-graz.ac.at)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <libdragon.h>
|
||||
|
||||
|
||||
#define BUFSIZE 0x8000
|
||||
#define SDRAM_START 0xb0000000
|
||||
|
||||
#define CHECKSUM_START 0x1000
|
||||
#define CHECKSUM_LENGTH 0x100000L
|
||||
#define CHECKSUM_HEADERPOS 0x10
|
||||
#define CHECKSUM_END (CHECKSUM_START + CHECKSUM_LENGTH)
|
||||
|
||||
#define CHECKSUM_STARTVALUE 0xf8ca4ddc
|
||||
|
||||
#define ROL(i, b) (((i)<<(b)) | ((i)>>(32-(b))))
|
||||
|
||||
#define BYTES2LONG(b) ( (((b)[0] & 0xffL) << 24) | \
|
||||
(((b)[1] & 0xffL) << 16) | \
|
||||
(((b)[2] & 0xffL) << 8) | \
|
||||
(((b)[3] & 0xffL)) )
|
||||
|
||||
#define LONG2BYTES(l, b) (b)[0] = ((l)>>24)&0xff; \
|
||||
(b)[1] = ((l)>>16)&0xff; \
|
||||
(b)[2] = ((l)>> 8)&0xff; \
|
||||
(b)[3] = ((l) )&0xff;
|
||||
|
||||
|
||||
static unsigned char __attribute__((aligned(16))) buffer1[BUFSIZE];
|
||||
|
||||
|
||||
void checksum_sdram(void)
|
||||
{
|
||||
unsigned int sum1, sum2, offs;
|
||||
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int c1, k1, k2;
|
||||
unsigned int t1, t2, t3, t4;
|
||||
unsigned int t5, t6;
|
||||
unsigned int n;
|
||||
unsigned int clen = CHECKSUM_LENGTH;
|
||||
|
||||
t1 = CHECKSUM_STARTVALUE;
|
||||
t2 = CHECKSUM_STARTVALUE;
|
||||
t3 = CHECKSUM_STARTVALUE;
|
||||
t4 = CHECKSUM_STARTVALUE;
|
||||
t5 = CHECKSUM_STARTVALUE;
|
||||
t6 = CHECKSUM_STARTVALUE;
|
||||
|
||||
offs = CHECKSUM_START;
|
||||
|
||||
for( ;; ) {
|
||||
n = (BUFSIZE < clen) ? BUFSIZE : clen;
|
||||
dma_read_s(buffer1, SDRAM_START+offs, n);
|
||||
data_cache_hit_writeback_invalidate(buffer1,n);
|
||||
|
||||
offs += n;
|
||||
|
||||
for( i=0; i<n; i+=4 ) {
|
||||
c1 = BYTES2LONG(&buffer1[i]);
|
||||
k1 = t6 + c1;
|
||||
if( k1 < t6 ) t4++;
|
||||
t6 = k1;
|
||||
t3 ^= c1;
|
||||
k2 = c1 & 0x1f;
|
||||
k1 = ROL(c1, k2);
|
||||
t5 += k1;
|
||||
if( c1 < t2 ) {
|
||||
t2 ^= k1;
|
||||
} else {
|
||||
t2 ^= t6 ^ c1;
|
||||
}
|
||||
t1 += c1 ^ t5;
|
||||
}
|
||||
clen -= n;
|
||||
if (!clen) break;
|
||||
}
|
||||
sum1 = t6 ^ t4 ^ t3;
|
||||
sum2 = t5 ^ t2 ^ t1;
|
||||
}
|
||||
LONG2BYTES(sum1, &buffer1[0]);
|
||||
LONG2BYTES(sum2, &buffer1[4]);
|
||||
dma_write_s(buffer1, SDRAM_START+CHECKSUM_HEADERPOS, 8);
|
||||
return;
|
||||
}
|
711
disk.c
Normal file
711
disk.c
Normal file
@ -0,0 +1,711 @@
|
||||
|
||||
|
||||
|
||||
#include <console.h>
|
||||
|
||||
#include "disk.h"
|
||||
#include "mem.h"
|
||||
#include "everdrive.h"
|
||||
#include "errors.h"
|
||||
#include "sys.h"
|
||||
#include "usb.h"
|
||||
|
||||
#define CMD0 0x40 // software reset
|
||||
#define CMD1 0x41 // brings card out of idle state
|
||||
#define CMD8 0x48 // Reserved
|
||||
#define CMD12 0x4C // stop transmission on multiple block read
|
||||
#define CMD17 0x51 // read single block
|
||||
#define CMD18 0x52 // read multiple block
|
||||
#define CMD58 0x7A // reads the OCR register
|
||||
#define CMD55 0x77
|
||||
#define CMD41 0x69
|
||||
#define CMD24 0x58 // writes a single block
|
||||
#define CMD25 0x59 // writes a multi block
|
||||
#define ACMD41 0x69
|
||||
#define ACMD6 0x46
|
||||
#define SD_V2 2
|
||||
#define SD_HC 1
|
||||
|
||||
|
||||
#define CMD2 0x42 //read cid
|
||||
#define CMD3 0x43 //read rca
|
||||
#define CMD7 0x47
|
||||
#define CMD9 0x49
|
||||
#define CMD6 0x46
|
||||
|
||||
#define R1 1
|
||||
#define R2 2
|
||||
#define R3 3
|
||||
#define R6 6
|
||||
#define R7 7
|
||||
|
||||
u8 card_type;
|
||||
u8 sd_resp_buff[18];
|
||||
u32 disk_interface;
|
||||
|
||||
|
||||
|
||||
unsigned int diskCrc7(unsigned char *buff, unsigned int len);
|
||||
void diskCrc16SD(u8 *data, u16 *crc_out, u16 len);
|
||||
u8 diskGetRespTypeSD(u8 cmd);
|
||||
u8 diskCmdSD(u8 cmd, u32 arg);
|
||||
|
||||
u8 diskInitSD();
|
||||
u8 diskReadSD(u32 saddr, void *buff, u16 slen);
|
||||
u8 diskWriteSD(u32 saddr, u8 *buff, u16 slen);
|
||||
u8 diskStopRwSD();
|
||||
|
||||
u8 diskCmdSPI(u8 cmd, u32 arg);
|
||||
u8 diskInitSPI();
|
||||
u8 diskReadSPI(u32 saddr, void *buff, u16 slen);
|
||||
u8 diskWriteSPI(u32 saddr, u8 *buff, u16 slen);
|
||||
|
||||
|
||||
|
||||
const u16 sd_crc16_table[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
|
||||
void diskSetInterface(u32 interface) {
|
||||
|
||||
disk_interface = interface;
|
||||
}
|
||||
|
||||
u8 diskGetInterface() {
|
||||
|
||||
return disk_interface;
|
||||
}
|
||||
|
||||
u8 diskInit() {
|
||||
|
||||
if (disk_interface == DISK_IFACE_SD) {
|
||||
return diskInitSD();
|
||||
} else {
|
||||
return diskInitSPI();
|
||||
}
|
||||
}
|
||||
|
||||
u8 diskRead(u32 saddr, void *buff, u16 slen) {
|
||||
|
||||
if (disk_interface == DISK_IFACE_SD) {
|
||||
return diskReadSD(saddr, buff, slen);
|
||||
} else {
|
||||
return diskReadSPI(saddr, buff, slen);
|
||||
}
|
||||
}
|
||||
|
||||
u8 diskWrite(u32 saddr, u8 *buff, u16 slen) {
|
||||
|
||||
if (disk_interface == DISK_IFACE_SD) {
|
||||
return diskWriteSD(saddr, buff, slen);
|
||||
} else {
|
||||
return diskWriteSPI(saddr, buff, slen);
|
||||
}
|
||||
}
|
||||
|
||||
void diskCrc16SD(u8 *data, u16 *crc_out, u16 len) {
|
||||
|
||||
///u16 len = 512;
|
||||
u16 i, tmp1, u;
|
||||
u8 dat[4];
|
||||
u8 dat_tmp;
|
||||
u16 crc_buff[4];
|
||||
|
||||
|
||||
for (i = 0; i < 4; i++)crc_buff[i] = 0;
|
||||
for (i = 0; i < 4; i++)crc_out[i] = 0;
|
||||
//u16 dptr = 0;
|
||||
while (len) {
|
||||
len -= 4;
|
||||
for (i = 0; i < 4; i++)dat[i] = 0;
|
||||
|
||||
for (u = 0; u < 4; u++) {
|
||||
dat_tmp = data[3 - u];
|
||||
//dat_tmp = 0xff;
|
||||
for (i = 0; i < 4; i++) {
|
||||
dat[i] >>= 1;
|
||||
dat[i] |= (dat_tmp & 1) << 7;
|
||||
dat_tmp >>= 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
dat[i] >>= 1;
|
||||
dat[i] |= (dat_tmp & 1) << 7;
|
||||
dat_tmp >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
data += 4;
|
||||
|
||||
for (u = 0; u < 4; u++) {
|
||||
tmp1 = crc_buff[u];
|
||||
crc_buff[u] = sd_crc16_table[(tmp1 >> 8) ^ dat[u]];
|
||||
crc_buff[u] = crc_buff[u] ^ (tmp1 << 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < 4 * 16; i++) {
|
||||
|
||||
crc_out[3 - i / 16] >>= 1;
|
||||
crc_out[3 - i / 16] |= (crc_buff[i % 4] & 1) << 15;
|
||||
crc_buff[i % 4] >>= 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned int diskCrc7(unsigned char *buff, unsigned int len) {
|
||||
|
||||
unsigned int a, crc = 0;
|
||||
|
||||
while (len--) {
|
||||
crc ^= *buff++;
|
||||
a = 8;
|
||||
do {
|
||||
crc <<= 1;
|
||||
if (crc & (1 << 8)) crc ^= 0x12;
|
||||
} while (--a);
|
||||
}
|
||||
return (crc & 0xfe);
|
||||
}
|
||||
|
||||
u8 diskGetRespTypeSD(u8 cmd) {
|
||||
|
||||
switch (cmd) {
|
||||
case CMD3:
|
||||
return R6;
|
||||
case CMD8:
|
||||
return R7;
|
||||
case CMD2:
|
||||
case CMD9:
|
||||
return R2;
|
||||
case CMD58:
|
||||
case CMD41:
|
||||
return R3;
|
||||
|
||||
default: return R1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u8 diskCmdSD(u8 cmd, u32 arg) {
|
||||
|
||||
u8 resp_type = diskGetRespTypeSD(cmd);
|
||||
u8 p = 0;
|
||||
u8 buff[6];
|
||||
volatile u8 resp;
|
||||
volatile u32 i = 0;
|
||||
|
||||
u8 resp_len = resp_type == R2 ? 17 : 6;
|
||||
u8 crc;
|
||||
buff[p++] = cmd;
|
||||
buff[p++] = (arg >> 24);
|
||||
buff[p++] = (arg >> 16);
|
||||
buff[p++] = (arg >> 8);
|
||||
buff[p++] = (arg >> 0);
|
||||
crc = diskCrc7(buff, 5) | 1;
|
||||
|
||||
evd_SDcmdWriteMode(0);
|
||||
|
||||
mem_spi(0xff);
|
||||
mem_spi(cmd);
|
||||
mem_spi(arg >> 24);
|
||||
mem_spi(arg >> 16);
|
||||
mem_spi(arg >> 8);
|
||||
mem_spi(arg);
|
||||
mem_spi(crc);
|
||||
evd_SDcmdReadMode(1);
|
||||
|
||||
i = 0;
|
||||
resp = 0xff;
|
||||
while ((resp & 192) != 0) {
|
||||
resp = mem_spi(resp);
|
||||
if (i++ == WAIT)return SD_CMD_TIMEOUT;
|
||||
}
|
||||
evd_SDcmdReadMode(0);
|
||||
|
||||
|
||||
sd_resp_buff[0] = resp;
|
||||
|
||||
for (i = 1; i < resp_len; i++) {
|
||||
sd_resp_buff[i] = mem_spi(0xff);
|
||||
}
|
||||
|
||||
if (resp_type != R3) {
|
||||
|
||||
|
||||
|
||||
if (resp_type == R2) {
|
||||
crc = diskCrc7(sd_resp_buff + 1, resp_len - 2) | 1;
|
||||
} else {
|
||||
crc = diskCrc7(sd_resp_buff, resp_len - 1) | 1;
|
||||
}
|
||||
if (crc != sd_resp_buff[resp_len - 1])return SD_CMD_CRC_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 diskInitSD() {
|
||||
|
||||
u16 i;
|
||||
volatile u8 resp = 0;
|
||||
u32 rca;
|
||||
u32 wait_len = WAIT;
|
||||
|
||||
card_type = 0;
|
||||
evd_enableSDMode();
|
||||
memSpiSSOff();
|
||||
memSpiSetSpeed(SPI_SPEED_INIT);
|
||||
|
||||
evd_SDcmdWriteMode(0);
|
||||
|
||||
for (i = 0; i < 40; i++)mem_spi(0xff);
|
||||
resp = diskCmdSD(CMD0, 0x1aa);
|
||||
for (i = 0; i < 40; i++)mem_spi(0xff);
|
||||
|
||||
|
||||
resp = diskCmdSD(CMD8, 0x1aa);
|
||||
if (resp != 0 && resp != SD_CMD_TIMEOUT) {
|
||||
return SD_INIT_ERROR + 0;
|
||||
}
|
||||
if (resp == 0)card_type |= SD_V2;
|
||||
|
||||
|
||||
if (card_type == SD_V2) {
|
||||
|
||||
for (i = 0; i < wait_len; i++) {
|
||||
|
||||
resp = diskCmdSD(CMD55, 0);
|
||||
if (resp)return SD_INIT_ERROR + 1;
|
||||
if ((sd_resp_buff[3] & 1) != 1)continue;
|
||||
resp = diskCmdSD(CMD41, 0x40300000);
|
||||
if ((sd_resp_buff[1] & 128) == 0)continue;
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
resp = diskCmdSD(CMD55, 0);
|
||||
if (resp)return SD_INIT_ERROR + 2;
|
||||
resp = diskCmdSD(CMD41, 0x40300000);
|
||||
if (resp)return SD_INIT_ERROR + 3;
|
||||
|
||||
} while (sd_resp_buff[1] < 1 && i++ < wait_len);
|
||||
|
||||
}
|
||||
|
||||
if (i == wait_len)return SD_INIT_ERROR + 4;
|
||||
|
||||
if ((sd_resp_buff[1] & 64) && card_type != 0)card_type |= SD_HC;
|
||||
|
||||
|
||||
resp = diskCmdSD(CMD2, 0);
|
||||
if (resp)return SD_INIT_ERROR + 5;
|
||||
|
||||
resp = diskCmdSD(CMD3, 0);
|
||||
if (resp)return SD_INIT_ERROR + 6;
|
||||
|
||||
resp = diskCmdSD(CMD7, 0);
|
||||
//if (resp)return resp;
|
||||
|
||||
rca = (sd_resp_buff[1] << 24) | (sd_resp_buff[2] << 16) | (sd_resp_buff[3] << 8) | (sd_resp_buff[4] << 0);
|
||||
|
||||
|
||||
|
||||
|
||||
resp = diskCmdSD(CMD9, rca); //get csd
|
||||
if (resp)return SD_INIT_ERROR + 7;
|
||||
|
||||
|
||||
resp = diskCmdSD(CMD7, rca);
|
||||
if (resp)return SD_INIT_ERROR + 8;
|
||||
|
||||
|
||||
resp = diskCmdSD(CMD55, rca);
|
||||
if (resp)return SD_INIT_ERROR + 9;
|
||||
|
||||
|
||||
resp = diskCmdSD(CMD6, 2);
|
||||
if (resp)return SD_INIT_ERROR + 10;
|
||||
|
||||
|
||||
memSpiSetSpeed(SPI_SPEED_25);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
u8 diskReadSD(u32 saddr, void *buff, u16 slen) {
|
||||
|
||||
u8 resp;
|
||||
|
||||
|
||||
if (!(card_type & 1))saddr *= 512;
|
||||
resp = diskCmdSD(CMD18, saddr);
|
||||
if (resp)return DISK_ERR_RD1;
|
||||
|
||||
|
||||
resp = memSpiRead(buff, slen);
|
||||
if (resp)return resp;
|
||||
|
||||
//console_printf("drd: %0X\n", saddr);
|
||||
resp = diskStopRwSD();
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
u8 diskStopRwSD() {
|
||||
|
||||
u8 resp;
|
||||
u16 i;
|
||||
resp = diskCmdSD(CMD12, 0);
|
||||
if (resp)return DISK_ERR_CLOSE_RW1;
|
||||
evd_SDdatReadMode(0);
|
||||
mem_spi(0xff);
|
||||
|
||||
i = 65535;
|
||||
while (i--) {
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
}
|
||||
if (i == 0)return DISK_ERR_CLOSE_RW2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 diskWriteSD(u32 saddr, u8 *buff, u16 slen) {
|
||||
|
||||
u8 resp;
|
||||
u16 crc16[5];
|
||||
u16 i;
|
||||
u16 u;
|
||||
u8 ram_buff[512];
|
||||
u8 *buff_ptr;
|
||||
|
||||
|
||||
if (!(card_type & 1))saddr *= 512;
|
||||
resp = diskCmdSD(CMD25, saddr);
|
||||
if (resp)return DISK_ERR_WR1;
|
||||
|
||||
evd_SDdatWriteMode(0);
|
||||
|
||||
|
||||
while (slen--) {
|
||||
|
||||
if ((u32) buff >= ROM_ADDR && (u32) buff < ROM_END_ADDR) {
|
||||
dma_read_s(ram_buff, (u32) buff, 512);
|
||||
buff_ptr = ram_buff;
|
||||
} else {
|
||||
buff_ptr = buff;
|
||||
}
|
||||
|
||||
diskCrc16SD(buff_ptr, crc16, 512);
|
||||
evd_SDdatWriteMode(0);
|
||||
|
||||
|
||||
mem_spi(0xff);
|
||||
mem_spi(0xf0);
|
||||
|
||||
|
||||
memSpiWrite(buff_ptr);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
mem_spi(crc16[i] >> 8);
|
||||
mem_spi(crc16[i] & 0xff);
|
||||
}
|
||||
|
||||
buff += 512;
|
||||
|
||||
evd_SDdatWriteMode(1);
|
||||
mem_spi(0xff);
|
||||
evd_SDdatReadMode(1);
|
||||
|
||||
i = 1024;
|
||||
while ((mem_spi(0xff) & 1) != 0 && i-- != 0);
|
||||
if (i == 0)return DISK_WR_SB_TOUT;
|
||||
resp = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
resp <<= 1;
|
||||
u = mem_spi(0xff);
|
||||
resp |= u & 1;
|
||||
}
|
||||
resp &= 7;
|
||||
|
||||
if (resp != 0x02) {
|
||||
//console_printf("error blia: %0X\n", resp);
|
||||
// joyWait();
|
||||
if (resp == 5)return DISK_ERR_WR_CRC;
|
||||
return DISK_ERR_WRX;
|
||||
}
|
||||
|
||||
evd_SDdatReadMode(0);
|
||||
mem_spi(0xff);
|
||||
i = 65535;
|
||||
while (i--) {
|
||||
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
}
|
||||
if (i == 0)return DISK_ERR_WR2;
|
||||
}
|
||||
|
||||
resp = diskStopRwSD();
|
||||
if (resp)return resp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 diskCmdSPI(u8 cmd, u32 arg) {
|
||||
|
||||
|
||||
u8 crc;
|
||||
u8 p = 0;
|
||||
u8 buff[6];
|
||||
buff[p++] = cmd;
|
||||
buff[p++] = (arg >> 24);
|
||||
buff[p++] = (arg >> 16);
|
||||
buff[p++] = (arg >> 8);
|
||||
buff[p++] = (arg >> 0);
|
||||
|
||||
crc = diskCrc7(buff, 5) | 1;
|
||||
|
||||
volatile u32 i = 0;
|
||||
volatile u8 resp;
|
||||
memSpiBusy();
|
||||
memSpiSSOff();
|
||||
memSpiSSOn();
|
||||
//mem_spi(0x1);
|
||||
mem_spi(0xff);
|
||||
mem_spi(cmd);
|
||||
mem_spi(arg >> 24);
|
||||
mem_spi(arg >> 16);
|
||||
mem_spi(arg >> 8);
|
||||
mem_spi(arg);
|
||||
mem_spi(crc);
|
||||
mem_spi(0xff);
|
||||
resp = mem_spi(0xff);
|
||||
|
||||
// memSpiSSOn();
|
||||
|
||||
while (resp == 0xff) {
|
||||
resp = mem_spi(0xff);
|
||||
if (i++ == WAIT)break;
|
||||
}
|
||||
|
||||
memSpiSSOff();
|
||||
return resp;
|
||||
}
|
||||
|
||||
u8 diskInitSPI() {
|
||||
|
||||
u16 i;
|
||||
u32 u;
|
||||
|
||||
volatile u8 resp = 0;
|
||||
u8 cmd;
|
||||
u32 wait_len = WAIT;
|
||||
|
||||
card_type = 0;
|
||||
|
||||
evd_enableSPIMode();
|
||||
//return evd_mmcInit();
|
||||
|
||||
memSpiSetSpeed(SPI_SPEED_INIT);
|
||||
|
||||
for (u = 0; u < 4; u++) {
|
||||
for (i = 0; i < 40; i++)mem_spi(0xff);
|
||||
resp = diskCmdSPI(CMD0, 0);
|
||||
if (resp == 1)break;
|
||||
}
|
||||
|
||||
if (resp != 1) return DISK_ERR_INIT + 0;
|
||||
//mmcCmdCrc(0x7b, 0, 0x91);
|
||||
resp = diskCmdSPI(CMD8, 0x1aa);
|
||||
for (i = 0; i < 5; i++)mem_spi(0xff);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 1;
|
||||
if (resp != 5)card_type |= SD_V2;
|
||||
|
||||
if (card_type == 2) {
|
||||
|
||||
for (i = 0; i < wait_len; i++) {
|
||||
|
||||
|
||||
resp = diskCmdSPI(CMD55, 0xffff);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 2;
|
||||
if (resp != 1)continue;
|
||||
|
||||
resp = diskCmdSPI(CMD41, 0x40300000);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 3;
|
||||
if (resp != 0)continue;
|
||||
|
||||
break;
|
||||
}
|
||||
if (i == wait_len)return DISK_ERR_INIT + 4;
|
||||
|
||||
resp = diskCmdSPI(CMD58, 0);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 5;
|
||||
memSpiSSOn();
|
||||
resp = mem_spi(0xff);
|
||||
for (i = 0; i < 3; i++)mem_spi(0xff);
|
||||
if ((resp & 0x40))card_type |= 1;
|
||||
} else {
|
||||
|
||||
|
||||
i = 0;
|
||||
|
||||
resp = diskCmdSPI(CMD55, 0);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 6;
|
||||
resp = diskCmdSPI(CMD41, 0);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 7;
|
||||
cmd = resp;
|
||||
|
||||
for (i = 0; i < wait_len; i++) {
|
||||
if (resp < 1) {
|
||||
|
||||
resp = diskCmdSPI(CMD55, 0);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 8;
|
||||
if (resp != 1)continue;
|
||||
|
||||
resp = diskCmdSPI(CMD41, 0);
|
||||
if (resp == 0xff)return DISK_ERR_INIT + 9;
|
||||
if (resp != 0)continue;
|
||||
|
||||
} else {
|
||||
|
||||
resp = diskCmdSPI(CMD1, 0);
|
||||
if (resp != 0)continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (i == wait_len)return DISK_ERR_INIT + 10;
|
||||
|
||||
}
|
||||
|
||||
memSpiSetSpeed(SPI_SPEED_25);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 diskReadSPI(u32 saddr, void *buff, u16 slen) {
|
||||
|
||||
|
||||
u8 resp;
|
||||
|
||||
if (!(card_type & 1))saddr *= 512;
|
||||
resp = diskCmdSPI(CMD18, saddr);
|
||||
if (resp != 0)return DISK_ERR_RD1;
|
||||
memSpiSSOn();
|
||||
|
||||
resp = memSpiRead(buff, slen);
|
||||
|
||||
memSpiSSOff();
|
||||
diskCmdSPI(CMD12, 0);
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
u8 diskWriteSPI(u32 saddr, u8 *buff, u16 slen) {
|
||||
|
||||
u8 resp;
|
||||
u16 i;
|
||||
|
||||
if (!(card_type & 1))saddr *= 512;
|
||||
resp = diskCmdSPI(CMD25, saddr);
|
||||
if (resp != 0)return DISK_ERR_WR1;
|
||||
memSpiSSOn();
|
||||
|
||||
|
||||
while (slen--) {
|
||||
|
||||
mem_spi(0xff);
|
||||
mem_spi(0xff);
|
||||
mem_spi(0xfc);
|
||||
|
||||
|
||||
memSpiWrite(buff);
|
||||
|
||||
mem_spi(0xff);
|
||||
mem_spi(0xff);
|
||||
resp = mem_spi(0xff);
|
||||
//resp = mem_spi(0xff);
|
||||
|
||||
buff += 512;
|
||||
|
||||
|
||||
|
||||
if ((resp & 0x1f) != 0x05) {
|
||||
memSpiSSOff();
|
||||
return DISK_ERR_WRX;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 65535; i++) {
|
||||
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
if (mem_spi(0xff) == 0xff)break;
|
||||
}
|
||||
|
||||
|
||||
if (i == 65535) {
|
||||
memSpiSSOff();
|
||||
return DISK_ERR_WR2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mem_spi(0xfd);
|
||||
mem_spi(0xff);
|
||||
|
||||
for (i = 0; i < 65535; i++) {
|
||||
if ((mem_spi(0xff) & 1) != 0)break;
|
||||
if ((mem_spi(0xff) & 1) != 0)break;
|
||||
if ((mem_spi(0xff) & 1) != 0)break;
|
||||
if ((mem_spi(0xff) & 1) != 0)break;
|
||||
}
|
||||
memSpiSSOff();
|
||||
if (i == 65535) return DISK_ERR_WR3;
|
||||
|
||||
return 0;
|
||||
}
|
29
disk.h
Normal file
29
disk.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* File: disk.h
|
||||
* Author: krik
|
||||
*
|
||||
* Created on 2 Èþíü 2011 ã., 4:07
|
||||
*/
|
||||
|
||||
#ifndef _DISK_H
|
||||
#define _DISK_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
u8 diskGetInterface();
|
||||
u8 diskInit();
|
||||
u8 diskRead(u32 saddr, void *buff, u16 slen);
|
||||
u8 diskWrite(u32 saddr, u8 *buff, u16 slen);
|
||||
void diskSetInterface(u32 interface);
|
||||
|
||||
|
||||
|
||||
#define WAIT 1024
|
||||
|
||||
#define DISK_IFACE_SPI 0
|
||||
#define DISK_IFACE_SD 1
|
||||
|
||||
|
||||
|
||||
#endif /* _DISK_H */
|
||||
|
104
doc/functions.txt
Normal file
104
doc/functions.txt
Normal file
@ -0,0 +1,104 @@
|
||||
beta9
|
||||
|
||||
rom loading function flow:
|
||||
|
||||
main()
|
||||
|
||||
//init n64, fs, controller
|
||||
|
||||
//joypad loop
|
||||
//button (A) -> select rom
|
||||
|
||||
|
||||
loadrom(disp,name_file);
|
||||
//readout rom header
|
||||
//check if swapped
|
||||
evd_mmcSetDmaSwap(1);
|
||||
|
||||
//dma read file to 0xb0000000 cartspace
|
||||
diskRead();
|
||||
|
||||
//change key mapping
|
||||
|
||||
//if (START)
|
||||
bootRom();
|
||||
|
||||
//save LAST.CRT for reboot cart-save
|
||||
|
||||
//set fpga to eeprom, sram, flashram
|
||||
evd_setSaveType(boot_save);
|
||||
|
||||
//do pif simulation to boot the rom
|
||||
simulate_boot(boot_cic, bios_cic);
|
||||
|
||||
|
||||
|
||||
cart-save overview:
|
||||
|
||||
before pif simulation the cart_id and cart_savetype is stored in
|
||||
LAST.CRT [maybe it's a better solution to use rom filenames
|
||||
'cause the cart_id includes no game-version]
|
||||
-> bootRom();
|
||||
|
||||
at every start of the menu a function is called that checks
|
||||
LAST.CRT, if there is something todo and disable it for next boot
|
||||
by setting a flag in that file
|
||||
-> backupSaveData(disp);
|
||||
|
||||
if it's a warm boot (reset) the fpga savegame is still there
|
||||
-> save_cfg_stat = evd_readReg(REG_SAV_CFG);
|
||||
|
||||
if it's a reset reboot to backup a savegame into a file
|
||||
saveTypeToSd(disp, cartID, save_t)
|
||||
is called
|
||||
|
||||
it's only for some file operations and calls
|
||||
utils.c: getSaveFromCart(stype, cartsave_data)
|
||||
to store the savegame into a buffer, which could
|
||||
be saved into a file
|
||||
|
||||
|
||||
some notes:
|
||||
eeprom is connected directly to the pif (i2c?)
|
||||
and could be read out stable with the libdragon function
|
||||
|
||||
sram/flashram is a serial device that is mapped into
|
||||
memory
|
||||
it has to be accessed with dma to rdram through the pif
|
||||
|
||||
it's a domain2 device which needs other timing than the cart
|
||||
|
||||
timings:
|
||||
|
||||
PI_BSD_DOM2_XXX_REG
|
||||
|
||||
sram/fram:
|
||||
|
||||
val XXX desc
|
||||
05 LAT Latency
|
||||
OC PWD Pulse Width
|
||||
|
||||
//sram - 0D
|
||||
//fram Animal Forest - 0F
|
||||
OD PGS Page Size
|
||||
|
||||
02 RLS Release Duration
|
||||
|
||||
|
||||
carts/dev-carts:
|
||||
40 Latency
|
||||
12 Pulse Width
|
||||
07 Page Size
|
||||
03 Release Duration
|
||||
|
||||
IPL at 0xA6000000:
|
||||
40 Latency
|
||||
07 Pulse Width
|
||||
07 Page Size
|
||||
02 Release Duration
|
||||
|
||||
cartidge:
|
||||
PI_BSD_DOM1_XXX_REG
|
||||
|
||||
is set with the first word in the header
|
||||
e.g. 0x[80]371240 -> 3.7.12.40 ~ 40,12,07,03
|
70
errors.h
Normal file
70
errors.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* File: errors.h
|
||||
* Author: KRIK
|
||||
*
|
||||
* Created on 14 Ìàé 2011 ã., 7:17
|
||||
*/
|
||||
|
||||
#ifndef _ERRORS_H
|
||||
#define _ERRORS_H
|
||||
|
||||
|
||||
#define EVD_ERROR_FIFO_TIMEOUT 90;
|
||||
#define EVD_ERROR_MMC_TIMEOUT 91;
|
||||
|
||||
#define BOOT_UPD_ERR_WRONG_SIZE 95
|
||||
#define BOOT_UPD_ERR_HDR 96
|
||||
#define BOOT_UPD_ERR_CMP 97
|
||||
#define BOOT_UPD_ERR_CIC_DTCT 98
|
||||
|
||||
#define FAT_ERR_NOT_EXIST 100
|
||||
#define FAT_ERR_EXIST 101
|
||||
#define FAT_ERR_NAME 102
|
||||
#define FAT_ERR_OUT_OF_FILE 103
|
||||
#define FAT_ERR_BAD_BASE_CLUSTER 104;
|
||||
#define FAT_ERR_NO_FRE_SPACE 105
|
||||
#define FAT_ERR_NOT_FILE 106
|
||||
#define FAT_ERR_FILE_MODE 107
|
||||
#define FAT_ERR_ROT_OVERFLOW 108
|
||||
#define FAT_ERR_OUT_OF_TABLE 109
|
||||
#define FAT_ERR_INIT 110
|
||||
#define FAT_LFN_BUFF_OVERFLOW 111
|
||||
#define FAT_DISK_NOT_READY 112
|
||||
#define FAT_ERR_SIZE 113
|
||||
#define FAT_ERR_RESIZE 114
|
||||
|
||||
#define ERR_FILE8_TOO_BIG 140
|
||||
#define ERR_FILE16_TOO_BIG 141
|
||||
#define ERR_WRON_OS_SIZE 142
|
||||
#define ERR_OS_VERIFY 143
|
||||
#define ERR_OS_VERIFY2 144
|
||||
#define ERR_EMU_NOT_FOUND 145
|
||||
#define ERR_SAVE_FORMAT 146
|
||||
#define ERR_EEPROM 147
|
||||
#define ERR_NO_FAV_SPACE 150
|
||||
|
||||
|
||||
|
||||
#define DISK_ERR_INIT 50
|
||||
|
||||
#define DISK_ERR_RD1 62
|
||||
#define DISK_ERR_RD2 63
|
||||
|
||||
#define DISK_ERR_WR1 64
|
||||
#define DISK_ERR_WR2 65
|
||||
#define DISK_ERR_WR3 66
|
||||
#define DISK_ERR_WRX 67
|
||||
#define DISK_WR_SB_TOUT 68
|
||||
#define DISK_ERR_WR_CRC 69
|
||||
|
||||
#define DISK_RD_FE_TOUT 70
|
||||
#define DISK_ERR_CLOSE_RW1 71
|
||||
#define DISK_ERR_CLOSE_RW2 72
|
||||
|
||||
#define SD_CMD_TIMEOUT 75
|
||||
#define SD_CMD_CRC_ERROR 76
|
||||
|
||||
#define SD_INIT_ERROR 80
|
||||
|
||||
#endif /* _ERRORS_H */
|
||||
|
596
everdrive.c
Normal file
596
everdrive.c
Normal file
@ -0,0 +1,596 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "everdrive.h"
|
||||
#include <libdragon.h>
|
||||
#include <stdio.h>
|
||||
#include "sys.h"
|
||||
#include "errors.h"
|
||||
//#include "rom.h"
|
||||
#include "disk.h"
|
||||
|
||||
#define CMD0 0x40 // software reset
|
||||
#define CMD1 0x41 // brings card out of idle state
|
||||
#define CMD2 0x42 // not used in SPI mode
|
||||
#define CMD3 0x43 // not used in SPI mode
|
||||
#define CMD4 0x44 // not used in SPI mode
|
||||
#define CMD5 0x45 // Reserved
|
||||
#define CMD6 0x46 // Reserved
|
||||
#define CMD7 0x47 // not used in SPI mode
|
||||
#define CMD8 0x48 // Reserved
|
||||
#define CMD9 0x49 // ask card to send card speficic data (CSD)
|
||||
#define CMD10 0x4A // ask card to send card identification (CID)
|
||||
#define CMD11 0x4B // not used in SPI mode
|
||||
#define CMD12 0x4C // stop transmission on multiple block read
|
||||
#define CMD13 0x4D // ask the card to send it's status register
|
||||
#define CMD14 0x4E // Reserved
|
||||
#define CMD15 0x4F // not used in SPI mode
|
||||
#define CMD16 0x50 // sets the block length used by the memory card
|
||||
#define CMD17 0x51 // read single block
|
||||
#define CMD18 0x52 // read multiple block
|
||||
#define CMD19 0x53 // Reserved
|
||||
#define CMD20 0x54 // not used in SPI mode
|
||||
#define CMD21 0x55 // Reserved
|
||||
#define CMD22 0x56 // Reserved
|
||||
#define CMD23 0x57 // Reserved
|
||||
#define CMD24 0x58 // writes a single block
|
||||
#define CMD25 0x59 // writes multiple blocks
|
||||
#define CMD26 0x5A // not used in SPI mode
|
||||
#define CMD27 0x5B // change the bits in CSD
|
||||
#define CMD28 0x5C // sets the write protection bit
|
||||
#define CMD29 0x5D // clears the write protection bit
|
||||
#define CMD30 0x5E // checks the write protection bit
|
||||
#define CMD31 0x5F // Reserved
|
||||
#define CMD32 0x60 // Sets the address of the first sector of the erase group
|
||||
#define CMD33 0x61 // Sets the address of the last sector of the erase group
|
||||
#define CMD34 0x62 // removes a sector from the selected group
|
||||
#define CMD35 0x63 // Sets the address of the first group
|
||||
#define CMD36 0x64 // Sets the address of the last erase group
|
||||
#define CMD37 0x65 // removes a group from the selected section
|
||||
#define CMD38 0x66 // erase all selected groups
|
||||
#define CMD39 0x67 // not used in SPI mode
|
||||
#define CMD40 0x68 // not used in SPI mode
|
||||
#define CMD41 0x69 // Reserved
|
||||
#define CMD42 0x6A // locks a block
|
||||
// CMD43 ... CMD57 are Reserved
|
||||
#define CMD58 0x7A // reads the OCR register
|
||||
#define CMD59 0x7B // turns CRC off
|
||||
// CMD60 ... CMD63 are not used in SPI mode
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define ED_STATE_DMA_BUSY 0
|
||||
#define ED_STATE_DMA_TOUT 1
|
||||
#define ED_STATE_TXE 2
|
||||
#define ED_STATE_RXF 3
|
||||
#define ED_STATE_SPI 4
|
||||
|
||||
#define SPI_CFG_SPD0 0
|
||||
#define SPI_CFG_SPD1 1
|
||||
#define SPI_CFG_SS 2
|
||||
#define SPI_CFG_RD 3
|
||||
#define SPI_CFG_DAT 4
|
||||
#define SPI_CFG_1BIT 5
|
||||
|
||||
#define SAV_EEP_ON 0
|
||||
#define SAV_SRM_ON 1
|
||||
#define SAV_EEP_SIZE 2
|
||||
#define SAV_SRM_SIZE 3
|
||||
|
||||
//was missing
|
||||
//#define BI_SPI_SPD_LO 0
|
||||
|
||||
#define BI_SPI_SPD_LO 2 // around 200khz (only for sd initialization)
|
||||
#define BI_SPI_SPD_25 1
|
||||
#define BI_SPI_SPD_50 0
|
||||
|
||||
|
||||
void evd_setSpiSpeed(u8 speed);
|
||||
u8 evd_mmcCmd(u8 cmd, u32 arg);
|
||||
|
||||
u8 sd_mode;
|
||||
volatile u8 spi_cfg;
|
||||
volatile u8 evd_cfg;
|
||||
u8 sd_type;
|
||||
volatile u32 *regs_ptr = (u32 *) 0xA8040000;
|
||||
|
||||
/*
|
||||
result[2] <= ad[15:8] == {ad[6], ad[1], ad[0], ad[7], ad[5], ad[4], ad[3], ad[2]} ^ 8'h37 ^ prv[7:0];
|
||||
prv[7:0] <= ad[15:8];
|
||||
*/
|
||||
void (*dma_busy_callback)();
|
||||
|
||||
|
||||
void evd_setDmaAddr(u32 addr) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline u32 bi_reg_rd(u32 reg) {
|
||||
|
||||
*(vu32 *) (REGS_BASE);
|
||||
return *(vu32 *) (REGS_BASE + reg * 4);
|
||||
}
|
||||
|
||||
inline void bi_reg_wr(u32 reg, u32 data) {
|
||||
|
||||
*(vu32 *) (REGS_BASE);
|
||||
*(vu32 *) (REGS_BASE + reg * 4) = data;
|
||||
}
|
||||
|
||||
|
||||
void bi_init() {
|
||||
|
||||
evd_cfg = ED_CFG_SDRAM_ON;
|
||||
spi_cfg = 0 | BI_SPI_SPD_LO;
|
||||
bi_reg_wr(REG_KEY, 0x1234);
|
||||
bi_reg_wr(REG_CFG, evd_cfg);
|
||||
bi_reg_wr(REG_SPI_CFG, spi_cfg);
|
||||
}
|
||||
|
||||
void bi_speed50() {
|
||||
|
||||
spi_cfg = 0 | BI_SPI_SPD_50;
|
||||
bi_reg_wr(REG_KEY, 0x1234);
|
||||
bi_reg_wr(REG_SPI_CFG, spi_cfg);
|
||||
}
|
||||
|
||||
void bi_speed25() {
|
||||
|
||||
spi_cfg = 0 | BI_SPI_SPD_25;
|
||||
bi_reg_wr(REG_KEY, 0x1234);
|
||||
bi_reg_wr(REG_SPI_CFG, spi_cfg);
|
||||
}
|
||||
|
||||
void bi_load_firmware(u8 *firm) {
|
||||
|
||||
u32 i;
|
||||
u16 f_ctr = 0;
|
||||
|
||||
|
||||
evd_cfg &= ~ED_CFG_SDRAM_ON;
|
||||
bi_reg_wr(REG_CFG, evd_cfg);
|
||||
|
||||
bi_reg_wr(REG_CFG_CNT, 0);
|
||||
sleep(10);
|
||||
bi_reg_wr(REG_CFG_CNT, 1);
|
||||
sleep(10);
|
||||
|
||||
i = 0;
|
||||
for (;;) {
|
||||
|
||||
bi_reg_wr(REG_CFG_DAT, *(u16 *) & firm[i]);
|
||||
while ((bi_reg_rd(REG_CFG_CNT) & 8) != 0);
|
||||
|
||||
f_ctr = firm[i++] == 0xff ? f_ctr + 1 : 0;
|
||||
if (f_ctr >= 47)break;
|
||||
f_ctr = firm[i++] == 0xff ? f_ctr + 1 : 0;
|
||||
if (f_ctr >= 47)break;
|
||||
}
|
||||
|
||||
|
||||
while ((bi_reg_rd(REG_CFG_CNT) & 4) == 0) {
|
||||
bi_reg_wr(REG_CFG_DAT, 0xffff);
|
||||
while ((bi_reg_rd(REG_CFG_CNT) & 8) != 0);
|
||||
}
|
||||
|
||||
|
||||
sleep(20);
|
||||
|
||||
bi_init();
|
||||
}
|
||||
|
||||
|
||||
void evd_init() {
|
||||
|
||||
volatile u8 val;
|
||||
sd_mode = 0;
|
||||
dma_busy_callback = 0;
|
||||
|
||||
sleep(1);
|
||||
val = regs_ptr[0];
|
||||
|
||||
spi_cfg = (0 << SPI_CFG_SPD0) | (1 << SPI_CFG_SPD1) | (1 << SPI_CFG_SS);
|
||||
evd_cfg = (1 << ED_CFG_SDRAM_ON);
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_KEY] = 0x1234;
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_CFG] = evd_cfg;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
|
||||
evd_fifoRxf();
|
||||
if (!evd_fifoRxf()) {
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_LEN] = 7; //clean 16k
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_RAM_ADDR] = (ROM_LEN - 0x200000) / 2048;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_CFG] = DCFG_FIFO_TO_RAM;
|
||||
while (evd_isDmaBusy());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void evd_ulockRegs(){
|
||||
volatile u8 val;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_KEY] = 0x1234;
|
||||
}
|
||||
|
||||
void evd_lockRegs() {
|
||||
volatile u8 val;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_KEY] = 0;
|
||||
}
|
||||
|
||||
u8 evd_fifoRxf() {
|
||||
|
||||
u16 val;
|
||||
//regs_ptr[REG_STATE]++;
|
||||
val = regs_ptr[REG_STATUS];
|
||||
return (val >> ED_STATE_RXF) & 1;
|
||||
}
|
||||
|
||||
u8 evd_fifoTxe() {
|
||||
|
||||
u16 val;
|
||||
//regs_ptr[REG_STATE]++;
|
||||
val = regs_ptr[REG_STATUS];
|
||||
return (val >> ED_STATE_TXE) & 1;
|
||||
}
|
||||
|
||||
u8 evd_isDmaBusy() {
|
||||
|
||||
u16 val;
|
||||
//volatile u32 i;
|
||||
sleep(1);
|
||||
if(dma_busy_callback != 0)dma_busy_callback();
|
||||
//regs_ptr[REG_STATE]++;
|
||||
val = regs_ptr[REG_STATUS];
|
||||
return (val >> ED_STATE_DMA_BUSY) & 1;
|
||||
}
|
||||
|
||||
u8 evd_isDmaTimeout() {
|
||||
|
||||
u16 val;
|
||||
//regs_ptr[REG_STATE]++;
|
||||
val = regs_ptr[REG_STATUS];
|
||||
|
||||
return (val >> ED_STATE_DMA_TOUT) & 1;
|
||||
}
|
||||
|
||||
u8 evd_fifoRdToCart(u32 cart_addr, u16 blocks) {
|
||||
|
||||
volatile u8 val;
|
||||
cart_addr /= 2048;
|
||||
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_LEN] = (blocks - 1);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_RAM_ADDR] = cart_addr;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_CFG] = DCFG_FIFO_TO_RAM;
|
||||
|
||||
while (evd_isDmaBusy());
|
||||
if (evd_isDmaTimeout())return EVD_ERROR_FIFO_TIMEOUT;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 evd_fifoWrFromCart(u32 cart_addr, u16 blocks) {
|
||||
|
||||
volatile u8 val;
|
||||
cart_addr /= 2048;
|
||||
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_LEN] = (blocks - 1);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_RAM_ADDR] = cart_addr;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_CFG] = DCFG_RAM_TO_FIFO;
|
||||
|
||||
while (evd_isDmaBusy());
|
||||
if (evd_isDmaTimeout())return EVD_ERROR_FIFO_TIMEOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 evd_fifoRd(void *buff, u16 blocks) {
|
||||
|
||||
volatile u8 val;
|
||||
u32 len = blocks == 0 ? 65536 * 512 : blocks * 512;
|
||||
u32 ram_buff_addr = DMA_BUFF_ADDR / 2048; //(ROM_LEN - len - 65536 * 4) / 2048;
|
||||
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_LEN] = (blocks - 1);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_RAM_ADDR] = ram_buff_addr;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_CFG] = DCFG_FIFO_TO_RAM;
|
||||
|
||||
while (evd_isDmaBusy());
|
||||
dma_read_s(buff, (0xb0000000 + ram_buff_addr * 2048), len);
|
||||
if (evd_isDmaTimeout())return EVD_ERROR_FIFO_TIMEOUT;
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u8 evd_fifoWr(void *buff, u16 blocks) {
|
||||
|
||||
volatile u8 val;
|
||||
u32 len = blocks == 0 ? 65536 * 512 : blocks * 512;
|
||||
u32 ram_buff_addr = DMA_BUFF_ADDR / 2048; //(ROM_LEN - len - 65536 * 4) / 2048;
|
||||
|
||||
dma_write_s(buff, (0xb0000000 + ram_buff_addr * 1024 * 2), len);
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_LEN] = (blocks - 1);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_RAM_ADDR] = ram_buff_addr;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_CFG] = DCFG_RAM_TO_FIFO;
|
||||
|
||||
while (evd_isDmaBusy());
|
||||
if (evd_isDmaTimeout())return EVD_ERROR_FIFO_TIMEOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 evd_isSpiBusy() {
|
||||
|
||||
volatile u16 val;
|
||||
regs_ptr[REG_STATUS];
|
||||
val = regs_ptr[REG_STATUS];
|
||||
return (val >> ED_STATE_SPI) & 1;
|
||||
}
|
||||
|
||||
u8 evd_SPI(u8 dat) {
|
||||
|
||||
|
||||
volatile u8 val;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI] = dat;
|
||||
while (evd_isSpiBusy());
|
||||
//osInvalICache((u32*) & regs_ptr[REG_SPI], 1);
|
||||
val = regs_ptr[REG_SPI];
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
void evd_spiSSOn() {
|
||||
|
||||
volatile u8 val;
|
||||
if (sd_mode)return;
|
||||
spi_cfg &= ~(1 << SPI_CFG_SS);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
|
||||
}
|
||||
|
||||
void evd_spiSSOff() {
|
||||
|
||||
volatile u8 val;
|
||||
spi_cfg |= (1 << SPI_CFG_SS);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
|
||||
}
|
||||
|
||||
void evd_enableSDMode() {
|
||||
sd_mode = 1;
|
||||
}
|
||||
|
||||
void evd_enableSPIMode() {
|
||||
sd_mode = 0;
|
||||
}
|
||||
|
||||
u8 evd_isSDMode() {
|
||||
|
||||
return sd_mode;
|
||||
}
|
||||
|
||||
void evd_SDcmdWriteMode(u8 bit1_mode) {
|
||||
|
||||
volatile u8 val;
|
||||
if (!sd_mode)return;
|
||||
spi_cfg &= ~((1 << SPI_CFG_RD) | (1 << SPI_CFG_DAT));
|
||||
if (bit1_mode) {
|
||||
spi_cfg |= (1 << SPI_CFG_1BIT);
|
||||
} else {
|
||||
spi_cfg &= ~(1 << SPI_CFG_1BIT);
|
||||
}
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
|
||||
}
|
||||
|
||||
void evd_SDcmdReadMode(u8 bit1_mode) {
|
||||
|
||||
|
||||
volatile u8 val;
|
||||
if (!sd_mode)return;
|
||||
spi_cfg |= (1 << SPI_CFG_RD);
|
||||
spi_cfg &= ~(1 << SPI_CFG_DAT);
|
||||
if (bit1_mode) {
|
||||
spi_cfg |= (1 << SPI_CFG_1BIT);
|
||||
} else {
|
||||
spi_cfg &= ~(1 << SPI_CFG_1BIT);
|
||||
}
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
}
|
||||
|
||||
void evd_SDdatWriteMode(u8 bit4_mode) {
|
||||
|
||||
|
||||
volatile u8 val;
|
||||
if (!sd_mode)return;
|
||||
spi_cfg &= ~(1 << SPI_CFG_RD);
|
||||
spi_cfg |= (1 << SPI_CFG_DAT);
|
||||
if (bit4_mode) {
|
||||
spi_cfg |= (1 << SPI_CFG_1BIT);
|
||||
} else {
|
||||
spi_cfg &= ~(1 << SPI_CFG_1BIT);
|
||||
}
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
}
|
||||
|
||||
void evd_SDdatReadMode(u8 bit4_mode) {
|
||||
|
||||
|
||||
volatile u8 val;
|
||||
if (!sd_mode)return;
|
||||
spi_cfg |= (1 << SPI_CFG_RD) | (1 << SPI_CFG_DAT);
|
||||
if (bit4_mode) {
|
||||
spi_cfg |= (1 << SPI_CFG_1BIT);
|
||||
} else {
|
||||
spi_cfg &= ~(1 << SPI_CFG_1BIT);
|
||||
}
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
}
|
||||
|
||||
void evd_setSpiSpeed(u8 speed) {
|
||||
|
||||
|
||||
volatile u8 val;
|
||||
spi_cfg &= ~3; //((1 << SPI_CFG_SPD0) | (1 << SPI_CFG_SPD1));
|
||||
spi_cfg |= speed & 3;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SPI_CFG] = spi_cfg;
|
||||
|
||||
|
||||
}
|
||||
|
||||
u8 evd_mmcReadToCart(u32 cart_addr, u32 len) {
|
||||
|
||||
volatile u8 val;
|
||||
cart_addr /= 2048;
|
||||
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_LEN] = (len - 1);
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_RAM_ADDR] = cart_addr;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_DMA_CFG] = DCFG_SD_TO_RAM;
|
||||
|
||||
while (evd_isDmaBusy());
|
||||
if (evd_isDmaTimeout())return EVD_ERROR_MMC_TIMEOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void evd_setCfgBit(u8 option, u8 state) {
|
||||
|
||||
volatile u8 val;
|
||||
|
||||
if (state)evd_cfg |= (1 << option);
|
||||
else
|
||||
evd_cfg &= ~(1 << option);
|
||||
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_CFG] = evd_cfg;
|
||||
val = regs_ptr[0];
|
||||
}
|
||||
|
||||
u16 evd_readReg(u8 reg) {
|
||||
|
||||
volatile u32 tmp;
|
||||
|
||||
tmp = regs_ptr[0];
|
||||
|
||||
return regs_ptr[reg];
|
||||
}
|
||||
|
||||
void evd_setSaveType(u8 type) {
|
||||
|
||||
|
||||
u8 eeprom_on, sram_on, eeprom_size, sram_size;
|
||||
eeprom_on = 0;
|
||||
sram_on = 0;
|
||||
eeprom_size = 0;
|
||||
sram_size = 0;
|
||||
|
||||
switch (type) {
|
||||
case SAVE_TYPE_EEP16k:
|
||||
eeprom_on = 1;
|
||||
eeprom_size = 1;
|
||||
break;
|
||||
case SAVE_TYPE_EEP4k:
|
||||
eeprom_on = 1;
|
||||
break;
|
||||
case SAVE_TYPE_SRAM:
|
||||
sram_on = 1;
|
||||
break;
|
||||
case SAVE_TYPE_SRAM128:
|
||||
sram_on = 1;
|
||||
sram_size = 1;
|
||||
break;
|
||||
case SAVE_TYPE_FLASH:
|
||||
sram_on = 0;
|
||||
sram_size = 1;
|
||||
break;
|
||||
default:
|
||||
sram_on = 0;
|
||||
sram_size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
volatile u8 val;
|
||||
val = regs_ptr[0];
|
||||
regs_ptr[REG_SAV_CFG] = (eeprom_on << SAV_EEP_ON | sram_on << SAV_SRM_ON | eeprom_size << SAV_EEP_SIZE | sram_size << SAV_SRM_SIZE);
|
||||
|
||||
}
|
||||
|
||||
void evd_writeReg(u8 reg, u16 val) {
|
||||
|
||||
volatile u8 tmp;
|
||||
tmp = regs_ptr[0];
|
||||
regs_ptr[reg] = val;
|
||||
|
||||
}
|
||||
|
||||
void evd_mmcSetDmaSwap(u8 state) {
|
||||
|
||||
evd_setCfgBit(ED_CFG_SWAP, state);
|
||||
}
|
||||
|
||||
void evd_writeMsg(u8 dat) {
|
||||
|
||||
evd_writeReg(REG_MSG, dat);
|
||||
|
||||
}
|
||||
|
||||
u8 evd_readMsg() {
|
||||
return evd_readReg(REG_MSG);
|
||||
}
|
||||
|
||||
u16 evd_getFirmVersion() {
|
||||
|
||||
return evd_readReg(REG_VER);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void evd_setDmaCallback(void (*callback)()) {
|
||||
|
||||
|
||||
dma_busy_callback = callback;
|
||||
}
|
125
everdrive.h
Normal file
125
everdrive.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* File: everdrive.h
|
||||
* Author: KRIK
|
||||
*
|
||||
* Created on 22 Àïðåëü 2011 ã., 20:46
|
||||
*/
|
||||
|
||||
#ifndef _EVERDRIVE_H
|
||||
#define _EVERDRIVE_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define OS_VER "1.29"
|
||||
|
||||
#define ROM_LEN 0x4000000
|
||||
#define ROM_ADDR 0xb0000000
|
||||
#define ROM_END_ADDR (0xb0000000 + 0x4000000)
|
||||
|
||||
|
||||
#define SAVE_TYPE_OFF 0
|
||||
#define SAVE_TYPE_SRAM 1
|
||||
#define SAVE_TYPE_SRAM128 2
|
||||
#define SAVE_TYPE_EEP4k 3
|
||||
#define SAVE_TYPE_EEP16k 4
|
||||
#define SAVE_TYPE_FLASH 5
|
||||
|
||||
#define DMA_BUFF_ADDR (ROM_LEN - 0x100000)
|
||||
|
||||
#define REG_CFG 0
|
||||
#define REG_STATUS 1
|
||||
#define REG_DMA_LEN 2
|
||||
#define REG_DMA_RAM_ADDR 3
|
||||
#define REG_MSG 4
|
||||
#define REG_DMA_CFG 5
|
||||
#define REG_SPI 6
|
||||
#define REG_SPI_CFG 7
|
||||
#define REG_KEY 8
|
||||
#define REG_SAV_CFG 9
|
||||
#define REG_SEC 10
|
||||
#define REG_VER 11
|
||||
|
||||
|
||||
#define REG_CFG_CNT 16
|
||||
#define REG_CFG_DAT 17
|
||||
#define REG_MAX_MSG 18
|
||||
#define REG_CRC 19
|
||||
|
||||
|
||||
#define DCFG_SD_TO_RAM 1
|
||||
#define DCFG_RAM_TO_SD 2
|
||||
#define DCFG_FIFO_TO_RAM 3
|
||||
#define DCFG_RAM_TO_FIFO 4
|
||||
|
||||
#define ED_CFG_SDRAM_ON 0
|
||||
#define ED_CFG_SWAP 1
|
||||
#define ED_CFG_WR_MOD 2
|
||||
#define ED_CFG_WR_ADDR_MASK 3
|
||||
|
||||
//new firmware load
|
||||
#define REGS_BASE 0xA8040000
|
||||
//--
|
||||
|
||||
void evd_setCfgBit(u8 option, u8 state);
|
||||
|
||||
void evd_init();
|
||||
u8 evd_fifoRxf();
|
||||
u8 evd_fifoTxe();
|
||||
u8 evd_isDmaBusy();
|
||||
u8 evd_isDmaTimeout();
|
||||
u8 evd_fifoRd(void *buff, u16 blocks);
|
||||
u8 evd_fifoWr(void *buff, u16 blocks);
|
||||
u8 evd_fifoRdToCart(u32 cart_addr, u16 blocks);
|
||||
u8 evd_fifoWrFromCart(u32 cart_addr, u16 blocks);
|
||||
|
||||
u8 evd_SPI(u8 dat);
|
||||
void evd_mmcSetDmaSwap(u8 state);
|
||||
u8 evd_mmcReadToCart(u32 cart_addr, u32 len);
|
||||
|
||||
void evd_lockRegs();
|
||||
u16 evd_readReg(u8 reg);
|
||||
void evd_writeReg(u8 reg, u16 val);
|
||||
void evd_setSaveType(u8 type);
|
||||
|
||||
|
||||
u8 romLoadSettingsFromSD();
|
||||
u8 romSaveInfoToLog();
|
||||
void evd_writeMsg(u8 dat);
|
||||
u8 evd_readMsg();
|
||||
u16 evd_getFirmVersion();
|
||||
|
||||
void evd_spiSSOn();
|
||||
void evd_spiSSOff();
|
||||
u8 evd_isSpiBusy();
|
||||
void evd_setSpiSpeed(u8 speed);
|
||||
|
||||
void evd_SDcmdWriteMode(u8 bit1_mode);
|
||||
void evd_SDcmdReadMode(u8 bit1_mode);
|
||||
void evd_SDdatWriteMode(u8 bit4_mode);
|
||||
void evd_SDdatReadMode(u8 bit4_mode);
|
||||
void evd_enableSDMode();
|
||||
void evd_enableSPIMode();
|
||||
u8 evd_isSDMode();
|
||||
void evd_setDmaCallback(void (*callback)());
|
||||
|
||||
|
||||
//firmware upload
|
||||
extern u32 bi_reg_rd(u32 reg);
|
||||
extern void bi_reg_wr(u32 reg, u32 data);
|
||||
void bi_init();
|
||||
void bi_load_firmware(u8 *firm);
|
||||
void bi_speed25();
|
||||
void bi_speed50();
|
||||
|
||||
/*
|
||||
u8 evd_mmcWriteNextBlock(void *dat);
|
||||
u8 evd_mmcOpenWrite(u32 addr);
|
||||
u8 evd_mmcWriteBlock(void *dat, u32 addr);
|
||||
u8 evd_mmcInit();
|
||||
u8 evd_mmcReadBlock(void *dat, u32 addr);
|
||||
u8 evd_mmcOpenRead(u32 addr);
|
||||
u8 evd_mmcReadNextBlock(void *dat);
|
||||
void evd_mmcCloseRW();
|
||||
*/
|
||||
#endif /* _EVERDRIVE_H */
|
||||
|
128
fat.h
Normal file
128
fat.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* File: fat.h
|
||||
* Author: krik
|
||||
*
|
||||
* Created on 22 Ìàé 2011 ã., 1:06
|
||||
*/
|
||||
|
||||
#ifndef _FAT_H
|
||||
#define _FAT_H
|
||||
|
||||
#include "types.h"
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define FAT_MAX_DIR_SIZE 1024
|
||||
#define FAT_MAX_NAME_LEN 128
|
||||
#define FAT_MAX_NAME_LEN_S 256
|
||||
|
||||
#define FAT_TYPE_16 1
|
||||
#define FAT_TYPE_32 2
|
||||
|
||||
typedef struct {
|
||||
u8 name[FAT_MAX_NAME_LEN];
|
||||
u32 entry_cluster;
|
||||
u32 size;
|
||||
u32 hdr_sector;
|
||||
u16 hdr_idx;
|
||||
u16 fav_idx;
|
||||
u8 is_dir;
|
||||
} FatRecord;
|
||||
|
||||
typedef struct {
|
||||
u8 name[8];
|
||||
u8 ext[3];
|
||||
u8 attrib;
|
||||
u8 x[8];
|
||||
u16 cluster_hi;
|
||||
u16 time;
|
||||
u16 date;
|
||||
u16 cluster_lo;
|
||||
u32 size;
|
||||
} FatRecordHdr;
|
||||
|
||||
typedef struct {
|
||||
FatRecord * rec[FAT_MAX_DIR_SIZE];
|
||||
FatRecord * s_records[FAT_MAX_DIR_SIZE];
|
||||
u8 *path;
|
||||
u16 size;
|
||||
u32 entry_cluster;
|
||||
u32 entry_sector;
|
||||
u32 in_cluster_ptr;
|
||||
u32 current_cluster;
|
||||
u8 is_root;
|
||||
} Dir;
|
||||
|
||||
typedef struct {
|
||||
u32 pbr_entry;
|
||||
u32 root_entry;
|
||||
u32 fat_entry;
|
||||
u32 data_entry;
|
||||
u8 type;
|
||||
u8 cluster_size;
|
||||
u32 loaded_sector;
|
||||
u32 cluster_byte_size;
|
||||
u32 sectors_per_fat;
|
||||
} Fat;
|
||||
|
||||
typedef struct {
|
||||
u8 *table_buff;
|
||||
u8 *table_sector;
|
||||
u8 *data_sector;
|
||||
u32 data_sec_idx;
|
||||
u32 table_sec_idx;
|
||||
} FatCache;
|
||||
|
||||
typedef struct {
|
||||
u32 sector;
|
||||
u32 cluster;
|
||||
u32 sec_available;
|
||||
u16 in_cluster_ptr;
|
||||
FatRecord rec;
|
||||
u8 mode;
|
||||
} File;
|
||||
|
||||
|
||||
|
||||
extern Dir *dir;
|
||||
//extern Dir dir_o;
|
||||
extern File file;
|
||||
extern FatCache *fat_cache;
|
||||
//extern FatRecord rec_tmp;
|
||||
#define ED_ROOT "/ED64"
|
||||
#define ED_SAVE "/ED64/SDSAVE"
|
||||
#define ED_ROM_CFG "/ED64/SDSAVE/LAST.CRT"
|
||||
//#define ED_TEST_CFG "/MISC/test.dat"
|
||||
//#define ED_OPTIONS "/ED64/options.dat"
|
||||
//#define ED_FAVOR "/ED64/favor.dat"
|
||||
|
||||
//#define ED_SAVE_DMP "/EDMD/sav-dmp.bin"
|
||||
#define FILE_MODE_RD 1
|
||||
#define FILE_MODE_WR 2
|
||||
|
||||
u8 fatInit();
|
||||
u8 fatLoadDir(u32 cluster);
|
||||
u8 fatLoadDirByName(u8 *name);
|
||||
|
||||
u8 fatWriteFile(void *src, u32 sectors);
|
||||
u8 fatReadFile(void *dst, u32 sectors);
|
||||
u8 fatReadPartialFile(void *dst, u32 sectors, int b_offset);
|
||||
u8 fatCreateRecord(u8 *name, u8 is_dir, u8 check_exist);
|
||||
u8 fatOpenFileByeName(u8 *name, u32 wr_sectors);
|
||||
u8 fatFindRecord(u8 *name, FatRecord *rec, u8 is_dir);
|
||||
u8 fatOpenFile(FatRecord *rec, u32 wr_sectors);
|
||||
|
||||
u8 fatSkipSectors(u32 sectors);
|
||||
u8 fatCreateRecIfNotExist(u8 *name, u8 is_dir);
|
||||
u8 fatGetFullName(u8 *name, u32 dir_entry, u32 rec_entry);
|
||||
u8 fatOpenDirByName(u8 *name);
|
||||
void fatInitRam();
|
||||
|
||||
u8 streq(u8 *str1, u8 *str2);
|
||||
u8 streql(u8 *str1, u8 *str2, u8 len);
|
||||
u8 slen(u8 *str);
|
||||
void fatSortRecords();
|
||||
#endif /* _FAT_H */
|
||||
|
BIN
filesystem/bamboo.wav
Normal file
BIN
filesystem/bamboo.wav
Normal file
Binary file not shown.
BIN
filesystem/done.wav
Normal file
BIN
filesystem/done.wav
Normal file
Binary file not shown.
BIN
filesystem/ed64_mono.wav
Normal file
BIN
filesystem/ed64_mono.wav
Normal file
Binary file not shown.
BIN
filesystem/n64controller.sprite
Normal file
BIN
filesystem/n64controller.sprite
Normal file
Binary file not shown.
BIN
filesystem/sprites/background.sprite
Normal file
BIN
filesystem/sprites/background.sprite
Normal file
Binary file not shown.
BIN
filesystem/sprites/splash.sprite
Normal file
BIN
filesystem/sprites/splash.sprite
Normal file
Binary file not shown.
BIN
filesystem/warning.wav
Normal file
BIN
filesystem/warning.wav
Normal file
Binary file not shown.
275
font_patch/font.h
Normal file
275
font_patch/font.h
Normal file
@ -0,0 +1,275 @@
|
||||
|
||||
/**
|
||||
* @file font.h
|
||||
* @brief Font Data
|
||||
* @ingroup graphics
|
||||
*/
|
||||
#ifndef __LIBDRAGON_FONT
|
||||
#define __LIBDRAGON_FONT
|
||||
|
||||
/**
|
||||
* @brief saturnu future font
|
||||
* @ingroup graphics
|
||||
*/
|
||||
|
||||
|
||||
static unsigned char __font_data[2048] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 000 (.)
|
||||
0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, // Char 001 (.)
|
||||
0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, // Char 002 (.)
|
||||
0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, // Char 003 (.)
|
||||
0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, // Char 004 (.)
|
||||
0x3C, 0x3C, 0x18, 0xFF, 0xE7, 0x18, 0x3C, 0x00, // Char 005 (.)
|
||||
0x10, 0x38, 0x7C, 0xFE, 0xEE, 0x10, 0x38, 0x00, // Char 006 (.)
|
||||
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, // Char 007 (.)
|
||||
0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, // Char 008 (.)
|
||||
0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, // Char 009 (.)
|
||||
0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, // Char 010 (.)
|
||||
0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, // Char 011 (.)
|
||||
0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, // Char 012 (.)
|
||||
0x08, 0x0C, 0x0A, 0x0A, 0x08, 0x78, 0xF0, 0x00, // Char 013 (.)
|
||||
0x18, 0x14, 0x1A, 0x16, 0x72, 0xE2, 0x0E, 0x1C, // Char 014 (.)
|
||||
0x10, 0x54, 0x38, 0xEE, 0x38, 0x54, 0x10, 0x00, // Char 015 (.)
|
||||
0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, // Char 016 (.)
|
||||
0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, // Char 017 (.)
|
||||
0x18, 0x3C, 0x5A, 0x18, 0x5A, 0x3C, 0x18, 0x00, // Char 018 (.)
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, // Char 019 (.)
|
||||
0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x00, // Char 020 (.)
|
||||
0x1C, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, // Char 021 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, // Char 022 (.)
|
||||
0x18, 0x3C, 0x5A, 0x18, 0x5A, 0x3C, 0x18, 0x7E, // Char 023 (.)
|
||||
0x18, 0x3C, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 024 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0x5A, 0x3C, 0x18, 0x00, // Char 025 (.)
|
||||
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, // Char 026 (.)
|
||||
0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, // Char 027 (.)
|
||||
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, // Char 028 (.)
|
||||
0x00, 0x24, 0x42, 0xFF, 0x42, 0x24, 0x00, 0x00, // Char 029 (.)
|
||||
0x00, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0x00, 0x00, // Char 030 (.)
|
||||
0x00, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, // Char 031 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )
|
||||
0x3C, 0x3C, 0x3C, 0x38, 0x38, 0x00, 0x38, 0x00, // Char 033 (!)
|
||||
0x6C, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 034 (")
|
||||
0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0xFE, 0x6C, 0x00, // Char 035 (#)
|
||||
0x10, 0x7C, 0xD0, 0x7C, 0x16, 0xFC, 0x10, 0x00, // Char 036 ($)
|
||||
0x00, 0x66, 0xAC, 0xD8, 0x36, 0x6A, 0xCC, 0x00, // Char 037 (%)
|
||||
0x38, 0x4C, 0x38, 0x78, 0xCE, 0xCC, 0x7A, 0x00, // Char 038 (&)
|
||||
0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 039 (')
|
||||
0x38, 0x38, 0x60, 0x60, 0x60, 0x38, 0x38, 0x00, // Char 040 (()
|
||||
0x60, 0x78, 0x18, 0x18, 0x18, 0x78, 0x60, 0x00, // Char 041 ())
|
||||
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // Char 042 (*)
|
||||
0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00, // Char 043 (+)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, // Char 044 (,)
|
||||
0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Char 045 (-)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, // Char 046 (.)
|
||||
0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x00, // Char 047 (/)
|
||||
0xFC, 0xE6, 0xFE, 0xF6, 0xE6, 0xE6, 0xFE, 0x00, // Char 048 (0)
|
||||
0x3C, 0x7C, 0x7C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00, // Char 049 (1)
|
||||
0xFE, 0xE6, 0x06, 0x1E, 0xF0, 0xFE, 0xFE, 0x00, // Char 050 (2)
|
||||
0xFE, 0xFE, 0x06, 0x3E, 0x06, 0xFE, 0xFE, 0x00, // Char 051 (3)
|
||||
0xFC, 0xFC, 0x9C, 0x9C, 0xFE, 0x1C, 0x1C, 0x00, // Char 052 (4)
|
||||
0xFE, 0xC0, 0xFE, 0x0E, 0x0E, 0xEE, 0xFE, 0x00, // Char 053 (5)
|
||||
0xFE, 0xE0, 0xE0, 0xFE, 0xE6, 0xE6, 0xFE, 0x00, // Char 054 (6)
|
||||
0xFE, 0xCE, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x00, // Char 055 (7)
|
||||
0xFE, 0xE6, 0xE6, 0xFE, 0xE6, 0xE6, 0xFE, 0x00, // Char 056 (8)
|
||||
0xFE, 0xE6, 0xE6, 0xFE, 0x06, 0x06, 0xFE, 0x00, // Char 057 (9)
|
||||
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, // Char 058 (:)
|
||||
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x20, // Char 059 (;)
|
||||
0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, // Char 060 (<)
|
||||
0x00, 0x00, 0x7E, 0x70, 0x00, 0x7E, 0x7E, 0x00, // Char 061 (=)
|
||||
0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, // Char 062 (>)
|
||||
0xFC, 0xCC, 0x0C, 0x3C, 0x3C, 0x00, 0x3C, 0x00, // Char 063 (?)
|
||||
0xFE, 0xC2, 0xDE, 0xD6, 0xDE, 0xC0, 0xFE, 0x00, // Char 064 (@)
|
||||
0xFC, 0xEE, 0xE6, 0xFE, 0xE6, 0xE6, 0xE6, 0x00, // Char 065 (A)
|
||||
0xFC, 0xE4, 0xE4, 0xFE, 0xE6, 0xE6, 0xFE, 0x00, // Char 066 (B)
|
||||
0xFE, 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0x00, // Char 067 (C)
|
||||
0xFC, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xFE, 0x00, // Char 068 (D)
|
||||
0xFE, 0xE0, 0xE0, 0xFC, 0xE0, 0xFE, 0xFE, 0x00, // Char 069 (E)
|
||||
0xFE, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xE0, 0x00, // Char 070 (F)
|
||||
0xFE, 0xE2, 0xE2, 0xE0, 0xEE, 0xE2, 0xFE, 0x00, // Char 071 (G)
|
||||
0xE6, 0xE6, 0xE6, 0xFE, 0xE6, 0xE6, 0xE6, 0x00, // Char 072 (H)
|
||||
0x38, 0x38, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, // Char 073 (I)
|
||||
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0xFE, 0xFE, 0x00, // Char 074 (J)
|
||||
0xE8, 0xE8, 0xE8, 0xFE, 0xE6, 0xE6, 0xE6, 0x00, // Char 075 (K)
|
||||
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0x00, // Char 076 (L)
|
||||
0xF6, 0xFE, 0xEA, 0xEA, 0xE2, 0xE2, 0xE2, 0x00, // Char 077 (M)
|
||||
0xE6, 0xE6, 0xF6, 0xFE, 0xEE, 0xE6, 0xE6, 0x00, // Char 078 (N)
|
||||
0x7C, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xFC, 0x00, // Char 079 (O)
|
||||
0xFE, 0xE6, 0xE6, 0xFE, 0xE0, 0xE0, 0xE0, 0x00, // Char 080 (P)
|
||||
0xFE, 0xE6, 0xE6, 0xE6, 0xF6, 0xEE, 0xFE, 0x00, // Char 081 (Q)
|
||||
0xFE, 0xE6, 0xE6, 0xFC, 0xE6, 0xE6, 0xE6, 0x00, // Char 082 (R)
|
||||
0xFE, 0xE6, 0xE0, 0xFE, 0x06, 0xE6, 0xFE, 0x00, // Char 083 (S)
|
||||
0x7E, 0x7E, 0x38, 0x38, 0x38, 0x38, 0x38, 0x00, // Char 084 (T)
|
||||
0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xFE, 0x00, // Char 085 (U)
|
||||
0xE6, 0xE6, 0xE6, 0xE6, 0xEE, 0xFC, 0xF8, 0x00, // Char 086 (V)
|
||||
0xE2, 0xE2, 0xEA, 0xFE, 0xEE, 0xE6, 0xE2, 0x00, // Char 087 (W)
|
||||
0xEE, 0xEE, 0x78, 0x78, 0x78, 0xEE, 0xEE, 0x00, // Char 088 (X)
|
||||
0xE6, 0xE6, 0xFE, 0x3E, 0x38, 0x38, 0x38, 0x00, // Char 089 (Y)
|
||||
0xFE, 0xE6, 0xEE, 0x18, 0x30, 0xE6, 0xFE, 0x00, // Char 090 (Z)
|
||||
0xF8, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF8, 0x00, // Char 091 ([)
|
||||
0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, // Char 092 (\)
|
||||
0x7C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x7C, 0x00, // Char 093 (])
|
||||
0x38, 0x7C, 0xEE, 0xC6, 0x00, 0x00, 0x00, 0x00, // Char 094 (^)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, // Char 095 (_)
|
||||
0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 096 (`)
|
||||
0x00, 0x00, 0x7C, 0x0C, 0x7C, 0x6E, 0x7E, 0x00, // Char 097 (a)
|
||||
0xE0, 0xE0, 0x60, 0x7E, 0x66, 0x66, 0x7E, 0x00, // Char 098 (b)
|
||||
0x00, 0x00, 0x7E, 0x66, 0x60, 0x66, 0x7E, 0x00, // Char 099 (c)
|
||||
0x0C, 0x0C, 0x0C, 0x7C, 0x6C, 0x6E, 0x7E, 0x00, // Char 100 (d)
|
||||
0x00, 0x00, 0x7E, 0x66, 0x7E, 0x60, 0x7E, 0x00, // Char 101 (e)
|
||||
0x1C, 0x3C, 0x30, 0x38, 0x30, 0x30, 0x30, 0x00, // Char 102 (f)
|
||||
0x00, 0x00, 0x7E, 0x62, 0x62, 0x7E, 0x02, 0x7E, // Char 103 (g)
|
||||
0x60, 0x60, 0x7E, 0x7E, 0x62, 0x62, 0x62, 0x00, // Char 104 (h)
|
||||
0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 105 (i)
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0x7C, 0x00, // Char 106 (j)
|
||||
0x60, 0x60, 0x66, 0x6E, 0x7C, 0x7E, 0x66, 0x00, // Char 107 (k)
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x3C, 0x00, // Char 108 (l)
|
||||
0x00, 0x00, 0x7C, 0x7E, 0x6A, 0x6A, 0x6A, 0x00, // Char 109 (m)
|
||||
0x00, 0x00, 0x78, 0x6C, 0x64, 0x64, 0x64, 0x00, // Char 110 (n)
|
||||
0x00, 0x00, 0x7C, 0x46, 0x46, 0x46, 0x7E, 0x00, // Char 111 (o)
|
||||
0x00, 0x00, 0x7E, 0x66, 0x66, 0x7C, 0x60, 0x60, // Char 112 (p)
|
||||
0x00, 0x00, 0x7C, 0x6C, 0x6C, 0x3C, 0x0C, 0x0C, // Char 113 (q)
|
||||
0x00, 0x00, 0x7E, 0x76, 0x70, 0x70, 0x70, 0x00, // Char 114 (r)
|
||||
0x00, 0x00, 0x7C, 0x60, 0x7C, 0x04, 0x7C, 0x00, // Char 115 (s)
|
||||
0x00, 0x30, 0x78, 0x30, 0x30, 0x30, 0x38, 0x00, // Char 116 (t)
|
||||
0x00, 0x00, 0x6C, 0x6C, 0x6C, 0x6C, 0x3C, 0x00, // Char 117 (u)
|
||||
0x00, 0x00, 0x64, 0x64, 0x6C, 0x78, 0x70, 0x00, // Char 118 (v)
|
||||
0x00, 0x00, 0x56, 0x56, 0x56, 0x7E, 0x7E, 0x00, // Char 119 (w)
|
||||
0x00, 0x00, 0xEE, 0x6C, 0x38, 0x6C, 0xEE, 0x00, // Char 120 (x)
|
||||
0x00, 0x00, 0x4C, 0x4C, 0x4C, 0x7C, 0x0C, 0x7C, // Char 121 (y)
|
||||
0x00, 0x00, 0x7E, 0x18, 0x30, 0x60, 0x7E, 0x00, // Char 122 (z)
|
||||
0x0E, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0E, 0x00, // Char 123 ({)
|
||||
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, // Char 124 (|)
|
||||
0xE0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xE0, 0x00, // Char 125 (})
|
||||
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 126 (~)
|
||||
0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, // Char 127 (.)
|
||||
0x7C, 0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x18, 0x70, // Char 128 (.)
|
||||
0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, // Char 129 (.)
|
||||
0x0E, 0x10, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00, // Char 130 (.)
|
||||
0x7C, 0x82, 0x7C, 0x0C, 0x7C, 0x6E, 0x7E, 0x00, // Char 131 (.)
|
||||
0x6C, 0x00, 0x7C, 0x0C, 0x7C, 0x6E, 0x7E, 0x00, // Char 132 (.)
|
||||
0xE0, 0x10, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, // Char 133 (.)
|
||||
0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, // Char 134 (.)
|
||||
0x00, 0x00, 0x7C, 0xC0, 0xC0, 0x7C, 0x18, 0x70, // Char 135 (.)
|
||||
0x7C, 0x82, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00, // Char 136 (.)
|
||||
0x66, 0x00, 0x7E, 0x66, 0x7E, 0x60, 0x7E, 0x00, // Char 137 (.)
|
||||
0xE0, 0x10, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00, // Char 138 (.)
|
||||
0x66, 0x00, 0x38, 0x38, 0x38, 0x38, 0x3C, 0x00, // Char 139 (.)
|
||||
0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 140 (.)
|
||||
0xE0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 141 (.)
|
||||
0xC6, 0x00, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, // Char 142 (.)
|
||||
0x38, 0x38, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, // Char 143 (.)
|
||||
0x0E, 0x10, 0xFE, 0x60, 0x78, 0x60, 0xFE, 0x00, // Char 144 (.)
|
||||
0x00, 0x00, 0x7C, 0x12, 0x7E, 0xD0, 0x7E, 0x00, // Char 145 (.)
|
||||
0x7E, 0xC8, 0xC8, 0xFE, 0xC8, 0xC8, 0xCE, 0x00, // Char 146 (.)
|
||||
0x7C, 0x82, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // Char 147 (.)
|
||||
0x66, 0x00, 0x7C, 0x46, 0x46, 0x46, 0x7E, 0x00, // Char 148 (.)
|
||||
0xE0, 0x10, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // Char 149 (.)
|
||||
0x7C, 0x82, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, // Char 150 (.)
|
||||
0xE0, 0x10, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, // Char 151 (.)
|
||||
0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, // Char 152 (.)
|
||||
0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // Char 153 (.)
|
||||
0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // Char 154 (.)
|
||||
0x18, 0x7C, 0xD6, 0xD0, 0xD6, 0x7C, 0x18, 0x00, // Char 155 (.)
|
||||
0x38, 0x6C, 0x60, 0xF0, 0x60, 0xF2, 0xDC, 0x00, // Char 156 (.)
|
||||
0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x00, // Char 157 (.)
|
||||
0xF8, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE, 0xCC, 0x06, // Char 158 (.)
|
||||
0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, // Char 159 (.)
|
||||
0x0E, 0x10, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, // Char 160 (.)
|
||||
0x0E, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 161 (.)
|
||||
0x0E, 0x10, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // Char 162 (.)
|
||||
0x0E, 0x10, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, // Char 163 (.)
|
||||
0x66, 0x98, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x00, // Char 164 (.)
|
||||
0x66, 0x98, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0x00, // Char 165 (.)
|
||||
0x38, 0x0C, 0x3C, 0x34, 0x00, 0x7E, 0x00, 0x00, // Char 166 (.)
|
||||
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, // Char 167 (.)
|
||||
0x30, 0x00, 0x30, 0x60, 0xC6, 0xC6, 0x7C, 0x00, // Char 168 (.)
|
||||
0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, // Char 169 (.)
|
||||
0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, // Char 170 (.)
|
||||
0xC0, 0xC8, 0xD0, 0xFE, 0x46, 0x8C, 0x1E, 0x00, // Char 171 (.)
|
||||
0xC0, 0xC8, 0xD0, 0xEC, 0x5C, 0xBE, 0x0C, 0x00, // Char 172 (.)
|
||||
0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, // Char 173 (.)
|
||||
0x00, 0x36, 0x6C, 0xD8, 0x6C, 0x36, 0x00, 0x00, // Char 174 (.)
|
||||
0x00, 0xD8, 0x6C, 0x36, 0x6C, 0xD8, 0x00, 0x00, // Char 175 (.)
|
||||
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, // Char 176 (.)
|
||||
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, // Char 177 (.)
|
||||
0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE, // Char 178 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // Char 179 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, // Char 180 (.)
|
||||
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, // Char 181 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, // Char 182 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, // Char 183 (.)
|
||||
0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, // Char 184 (.)
|
||||
0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, // Char 185 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, // Char 186 (.)
|
||||
0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, // Char 187 (.)
|
||||
0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, // Char 188 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, // Char 189 (.)
|
||||
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, // Char 190 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, // Char 191 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, // Char 192 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, // Char 193 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, // Char 194 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, // Char 195 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 196 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, // Char 197 (.)
|
||||
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, // Char 198 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, // Char 199 (.)
|
||||
0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, // Char 200 (.)
|
||||
0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, // Char 201 (.)
|
||||
0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 202 (.)
|
||||
0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, // Char 203 (.)
|
||||
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, // Char 204 (.)
|
||||
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 205 (.)
|
||||
0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, // Char 206 (.)
|
||||
0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 207 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, // Char 208 (.)
|
||||
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, // Char 209 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, // Char 210 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, // Char 211 (.)
|
||||
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, // Char 212 (.)
|
||||
0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, // Char 213 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, // Char 214 (.)
|
||||
0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, // Char 215 (.)
|
||||
0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, // Char 216 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, // Char 217 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, // Char 218 (.)
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Char 219 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // Char 220 (.)
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, // Char 221 (.)
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, // Char 222 (.)
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // Char 223 (.)
|
||||
0x00, 0x00, 0x74, 0xCC, 0xC8, 0xDC, 0x76, 0x00, // Char 224 (.)
|
||||
0x78, 0xCC, 0xD8, 0xCC, 0xC6, 0xC6, 0xDC, 0x40, // Char 225 (.)
|
||||
0xFE, 0x62, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, // Char 226 (.)
|
||||
0x00, 0x02, 0x7E, 0xEC, 0x6C, 0x6C, 0x48, 0x00, // Char 227 (.)
|
||||
0xFE, 0x62, 0x30, 0x18, 0x30, 0x62, 0xFE, 0x00, // Char 228 (.)
|
||||
0x00, 0x00, 0x7E, 0xD0, 0xC8, 0xC8, 0x70, 0x00, // Char 229 (.)
|
||||
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xF8, 0x80, // Char 230 (.)
|
||||
0x00, 0x00, 0x7E, 0xD8, 0x18, 0x18, 0x10, 0x00, // Char 231 (.)
|
||||
0x38, 0x10, 0x7C, 0xD6, 0xD6, 0x7C, 0x10, 0x38, // Char 232 (.)
|
||||
0x7C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x7C, 0x00, // Char 233 (.)
|
||||
0x7C, 0xC6, 0xC6, 0xC6, 0x6C, 0x28, 0xEE, 0x00, // Char 234 (.)
|
||||
0x3C, 0x22, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, // Char 235 (.)
|
||||
0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, // Char 236 (.)
|
||||
0x00, 0x06, 0x7C, 0x9E, 0xF2, 0x7C, 0xC0, 0x00, // Char 237 (.)
|
||||
0x00, 0x00, 0x7C, 0xC0, 0xF8, 0xC0, 0x7C, 0x00, // Char 238 (.)
|
||||
0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, // Char 239 (.)
|
||||
0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, // Char 240 (.)
|
||||
0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, // Char 241 (.)
|
||||
0x30, 0x18, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0x00, // Char 242 (.)
|
||||
0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7C, 0x00, // Char 243 (.)
|
||||
0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, // Char 244 (.)
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, // Char 245 (.)
|
||||
0x00, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x00, 0x00, // Char 246 (.)
|
||||
0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, // Char 247 (.)
|
||||
0x38, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 248 (.)
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, // Char 249 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, // Char 250 (.)
|
||||
0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x00, // Char 251 (.)
|
||||
0xD8, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, // Char 252 (.)
|
||||
0xF0, 0x30, 0xC0, 0xF0, 0x00, 0x00, 0x00, 0x00, // Char 253 (.)
|
||||
0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, // Char 254 (.)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Char 255 (.)
|
||||
};
|
||||
|
||||
#endif
|
1
font_patch/info.txt
Normal file
1
font_patch/info.txt
Normal file
@ -0,0 +1 @@
|
||||
libdragon: include/font.h
|
BIN
header.ed64
Normal file
BIN
header.ed64
Normal file
Binary file not shown.
301
ini.c
Normal file
301
ini.c
Normal file
@ -0,0 +1,301 @@
|
||||
/* inih -- simple .INI file parser
|
||||
|
||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
||||
home page for more info:
|
||||
|
||||
http://code.google.com/p/inih/
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "ini.h"
|
||||
|
||||
#if !INI_USE_STACK
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#define MAX_SECTION 50
|
||||
#define MAX_NAME 50
|
||||
|
||||
|
||||
/* Strip whitespace chars off end of given string, in place. Return s. */
|
||||
static char* rstrip(char* s)
|
||||
{
|
||||
char* p = s + strlen(s);
|
||||
while (p > s && isspace((unsigned char)(*--p)))
|
||||
*p = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return pointer to first non-whitespace char in given string. */
|
||||
static char* lskip(const char* s)
|
||||
{
|
||||
while (*s && isspace((unsigned char)(*s)))
|
||||
s++;
|
||||
return (char*)s;
|
||||
}
|
||||
|
||||
/* Return pointer to first char c or ';' comment in given string, or pointer to
|
||||
null at end of string if neither found. ';' must be prefixed by a whitespace
|
||||
character to register as a comment. */
|
||||
static char* find_char_or_comment(const char* s, char c)
|
||||
{
|
||||
int was_whitespace = 0;
|
||||
while (*s && *s != c && !(was_whitespace && *s == ';')) {
|
||||
was_whitespace = isspace((unsigned char)(*s));
|
||||
s++;
|
||||
}
|
||||
return (char*)s;
|
||||
}
|
||||
|
||||
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
|
||||
static char* strncpy0(char* dest, const char* src, size_t size)
|
||||
{
|
||||
strncpy(dest, src, size);
|
||||
dest[size - 1] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_str(char* ini_string,
|
||||
int (*handler)(void*, const char*, const char*,
|
||||
const char*),
|
||||
void* user)
|
||||
{
|
||||
/* Uses a fair bit of stack (use heap instead if you need to) */
|
||||
#if INI_USE_STACK
|
||||
char line[INI_MAX_LINE];
|
||||
#else
|
||||
char* line;
|
||||
#endif
|
||||
char section[MAX_SECTION] = "";
|
||||
char prev_name[MAX_NAME] = "";
|
||||
|
||||
char* start;
|
||||
char* end;
|
||||
char* name;
|
||||
char* value;
|
||||
int lineno = 0;
|
||||
int error = 0;
|
||||
|
||||
#if !INI_USE_STACK
|
||||
line = (char*)malloc(INI_MAX_LINE);
|
||||
if (!line) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int i=1;
|
||||
char *ptr;
|
||||
|
||||
// initialisieren und ersten Abschnitt erstellen
|
||||
ptr = strtok(ini_string, "\n");
|
||||
|
||||
|
||||
/* Scan through file line by line */
|
||||
while(ptr != NULL) {
|
||||
|
||||
sprintf(line, "%s\n",ptr);
|
||||
ptr = strtok(NULL, "\n");
|
||||
// while (line=gets( ini_string) != NULL) {
|
||||
lineno++;
|
||||
|
||||
start = line;
|
||||
#if INI_ALLOW_BOM
|
||||
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
|
||||
(unsigned char)start[1] == 0xBB &&
|
||||
(unsigned char)start[2] == 0xBF) {
|
||||
start += 3;
|
||||
}
|
||||
#endif
|
||||
start = lskip(rstrip(start));
|
||||
|
||||
if (*start == ';' || *start == '#') {
|
||||
/* Per Python ConfigParser, allow '#' comments at start of line */
|
||||
}
|
||||
#if INI_ALLOW_MULTILINE
|
||||
else if (*prev_name && *start && start > line) {
|
||||
/* Non-black line with leading whitespace, treat as continuation
|
||||
of previous name's value (as per Python ConfigParser). */
|
||||
if (!handler(user, section, prev_name, start) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
#endif
|
||||
else if (*start == '[') {
|
||||
/* A "[section]" line */
|
||||
end = find_char_or_comment(start + 1, ']');
|
||||
if (*end == ']') {
|
||||
*end = '\0';
|
||||
strncpy0(section, start + 1, sizeof(section));
|
||||
*prev_name = '\0';
|
||||
}
|
||||
else if (!error) {
|
||||
/* No ']' found on section line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
else if (*start && *start != ';') {
|
||||
/* Not a comment, must be a name[=:]value pair */
|
||||
end = find_char_or_comment(start, '=');
|
||||
if (*end != '=') {
|
||||
end = find_char_or_comment(start, ':');
|
||||
}
|
||||
if (*end == '=' || *end == ':') {
|
||||
*end = '\0';
|
||||
name = rstrip(start);
|
||||
value = lskip(end + 1);
|
||||
end = find_char_or_comment(value, '\0');
|
||||
if (*end == ';')
|
||||
*end = '\0';
|
||||
rstrip(value);
|
||||
|
||||
/* Valid name[=:]value pair found, call handler */
|
||||
strncpy0(prev_name, name, sizeof(prev_name));
|
||||
if (!handler(user, section, name, value) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
else if (!error) {
|
||||
/* No '=' or ':' found on name[=:]value line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !INI_USE_STACK
|
||||
free(line);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_file(FILE* file,
|
||||
int (*handler)(void*, const char*, const char*,
|
||||
const char*),
|
||||
void* user)
|
||||
{
|
||||
/* Uses a fair bit of stack (use heap instead if you need to) */
|
||||
#if INI_USE_STACK
|
||||
char line[INI_MAX_LINE];
|
||||
#else
|
||||
char* line;
|
||||
#endif
|
||||
char section[MAX_SECTION] = "";
|
||||
char prev_name[MAX_NAME] = "";
|
||||
|
||||
char* start;
|
||||
char* end;
|
||||
char* name;
|
||||
char* value;
|
||||
int lineno = 0;
|
||||
int error = 0;
|
||||
|
||||
#if !INI_USE_STACK
|
||||
line = (char*)malloc(INI_MAX_LINE);
|
||||
if (!line) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Scan through file line by line */
|
||||
while (fgets(line, INI_MAX_LINE, file) != NULL) {
|
||||
lineno++;
|
||||
|
||||
start = line;
|
||||
#if INI_ALLOW_BOM
|
||||
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
|
||||
(unsigned char)start[1] == 0xBB &&
|
||||
(unsigned char)start[2] == 0xBF) {
|
||||
start += 3;
|
||||
}
|
||||
#endif
|
||||
start = lskip(rstrip(start));
|
||||
|
||||
if (*start == ';' || *start == '#') {
|
||||
/* Per Python ConfigParser, allow '#' comments at start of line */
|
||||
}
|
||||
#if INI_ALLOW_MULTILINE
|
||||
else if (*prev_name && *start && start > line) {
|
||||
/* Non-black line with leading whitespace, treat as continuation
|
||||
of previous name's value (as per Python ConfigParser). */
|
||||
if (!handler(user, section, prev_name, start) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
#endif
|
||||
else if (*start == '[') {
|
||||
/* A "[section]" line */
|
||||
end = find_char_or_comment(start + 1, ']');
|
||||
if (*end == ']') {
|
||||
*end = '\0';
|
||||
strncpy0(section, start + 1, sizeof(section));
|
||||
*prev_name = '\0';
|
||||
}
|
||||
else if (!error) {
|
||||
/* No ']' found on section line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
else if (*start && *start != ';') {
|
||||
/* Not a comment, must be a name[=:]value pair */
|
||||
end = find_char_or_comment(start, '=');
|
||||
if (*end != '=') {
|
||||
end = find_char_or_comment(start, ':');
|
||||
}
|
||||
if (*end == '=' || *end == ':') {
|
||||
*end = '\0';
|
||||
name = rstrip(start);
|
||||
value = lskip(end + 1);
|
||||
end = find_char_or_comment(value, '\0');
|
||||
if (*end == ';')
|
||||
*end = '\0';
|
||||
rstrip(value);
|
||||
|
||||
/* Valid name[=:]value pair found, call handler */
|
||||
strncpy0(prev_name, name, sizeof(prev_name));
|
||||
if (!handler(user, section, name, value) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
else if (!error) {
|
||||
/* No '=' or ':' found on name[=:]value line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !INI_USE_STACK
|
||||
free(line);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse(const char* filename,
|
||||
int (*handler)(void*, const char*, const char*, const char*),
|
||||
void* user)
|
||||
{
|
||||
FILE* file;
|
||||
int error;
|
||||
|
||||
// file = fopen(filename, "r");
|
||||
|
||||
|
||||
fputs(filename, file);
|
||||
|
||||
|
||||
|
||||
|
||||
if (!file)
|
||||
return -1;
|
||||
error = ini_parse_file(file, handler, user);
|
||||
fclose(file);
|
||||
return error;
|
||||
}
|
77
ini.h
Normal file
77
ini.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* inih -- simple .INI file parser
|
||||
|
||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
||||
home page for more info:
|
||||
|
||||
http://code.google.com/p/inih/
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __INI_H__
|
||||
#define __INI_H__
|
||||
|
||||
/* Make this header file easier to include in C++ code */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Parse given INI-style file. May have [section]s, name=value pairs
|
||||
(whitespace stripped), and comments starting with ';' (semicolon). Section
|
||||
is "" if name=value pair parsed before any section heading. name:value
|
||||
pairs are also supported as a concession to Python's ConfigParser.
|
||||
|
||||
For each name=value pair parsed, call handler function with given user
|
||||
pointer as well as section, name, and value (data only valid for duration
|
||||
of handler call). Handler should return nonzero on success, zero on error.
|
||||
|
||||
Returns 0 on success, line number of first error on parse error (doesn't
|
||||
stop on first error), -1 on file open error, or -2 on memory allocation
|
||||
error (only when INI_USE_STACK is zero).
|
||||
*/
|
||||
int ini_parse(const char* filename,
|
||||
int (*handler)(void* user, const char* section,
|
||||
const char* name, const char* value),
|
||||
void* user);
|
||||
|
||||
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
|
||||
close the file when it's finished -- the caller must do that. */
|
||||
int ini_parse_file(FILE* file,
|
||||
int (*handler)(void* user, const char* section,
|
||||
const char* name, const char* value),
|
||||
void* user);
|
||||
|
||||
int ini_parse_str(char* ini_string,
|
||||
int (*handler)(void*, const char*, const char*,
|
||||
const char*),
|
||||
void* user);
|
||||
|
||||
/* Nonzero to allow multi-line value parsing, in the style of Python's
|
||||
ConfigParser. If allowed, ini_parse() will call the handler with the same
|
||||
name for each subsequent line parsed. */
|
||||
#ifndef INI_ALLOW_MULTILINE
|
||||
#define INI_ALLOW_MULTILINE 1
|
||||
#endif
|
||||
|
||||
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
|
||||
the file. See http://code.google.com/p/inih/issues/detail?id=21 */
|
||||
#ifndef INI_ALLOW_BOM
|
||||
#define INI_ALLOW_BOM 1
|
||||
#endif
|
||||
|
||||
/* Nonzero to use stack, zero to use heap (malloc/free). */
|
||||
#ifndef INI_USE_STACK
|
||||
#define INI_USE_STACK 1
|
||||
#endif
|
||||
|
||||
/* Maximum line length for any line in INI file. */
|
||||
#ifndef INI_MAX_LINE
|
||||
#define INI_MAX_LINE 200
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INI_H__ */
|
160
mem.c
Normal file
160
mem.c
Normal file
@ -0,0 +1,160 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "everdrive.h"
|
||||
#include "sys.h"
|
||||
|
||||
u8 spi_dma;
|
||||
#include "errors.h"
|
||||
#include "mem.h"
|
||||
|
||||
u8 memSpiReadDma(void *dst, u16 slen);
|
||||
u8 memSpiReadPio(void *dst, u16 slen);
|
||||
u8 mem_buff[512];
|
||||
|
||||
void memSpiSetDma(u8 mode) {
|
||||
spi_dma = mode;
|
||||
}
|
||||
|
||||
void memcopy(void *src, void *dst, u16 len) {
|
||||
|
||||
u8 *s = (u8 *) src;
|
||||
u8 *d = (u8 *) dst;
|
||||
while (len--)*d++ = *s++;
|
||||
}
|
||||
|
||||
void memfill(void *dst, u8 val, u16 len) {
|
||||
u8 *d = (u8 *) dst;
|
||||
while (len--)*d++ = val;
|
||||
}
|
||||
|
||||
|
||||
// buff len
|
||||
u8 memSpiRead(void *dst, u16 slen) {
|
||||
|
||||
u8 copy_to_rom = 0;
|
||||
u32 addr = (u32) dst; //if ROM_ADDR 0xb0000000
|
||||
if (addr >= ROM_ADDR && addr < ROM_END_ADDR)copy_to_rom = 1;
|
||||
|
||||
//if (copy_to_rom || spi_dma) {
|
||||
if ((copy_to_rom || spi_dma) && addr % 4 == 0) {
|
||||
return memSpiReadDma(dst, slen);
|
||||
} else {
|
||||
return memSpiReadPio(dst, slen);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u8 memSpiReadPio(void *dst, u16 slen) {
|
||||
|
||||
u16 i;
|
||||
u16 u;
|
||||
u8 *ptr8 = (u8 *) dst;
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < slen; i++) {
|
||||
|
||||
evd_SDdatReadMode(1);
|
||||
for (u = 0; u < 65535; u++)if ((evd_SPI(0xff) & 0xf1) == 0xf0)break;
|
||||
evd_SDdatReadMode(0);
|
||||
if (u == 65535) {
|
||||
evd_spiSSOff();
|
||||
return DISK_RD_FE_TOUT;
|
||||
}
|
||||
|
||||
for (u = 0; u < 512; u++)*ptr8++ = evd_SPI(0xff);
|
||||
|
||||
u = evd_isSDMode() ? 8 : 2;
|
||||
|
||||
while (u--) {
|
||||
// console_printf("XRC: %02X", evd_SPI(0xff));
|
||||
//console_printf("%02X\n", evd_SPI(0xff));
|
||||
u--;
|
||||
evd_SPI(0xff);
|
||||
evd_SPI(0xff);
|
||||
}
|
||||
//evd_SPI(0xff);
|
||||
//evd_SPI(0xff);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 memSpiReadDma(void *dst, u16 slen) {
|
||||
|
||||
u8 resp = 0;
|
||||
u8 copy_to_rom = 0;
|
||||
u32 addr = (u32) dst;
|
||||
|
||||
evd_SDdatReadMode(0);
|
||||
// console_printf("dma\n");
|
||||
if (addr >= ROM_ADDR && addr < ROM_END_ADDR)copy_to_rom = 1;
|
||||
|
||||
if (copy_to_rom) {
|
||||
|
||||
return evd_mmcReadToCart(addr, slen);
|
||||
|
||||
} else {
|
||||
|
||||
resp = evd_mmcReadToCart(0, slen);
|
||||
dma_read_s(dst, ROM_ADDR, slen * 512);
|
||||
}
|
||||
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
u8 memSpiWrite(void *src) {
|
||||
|
||||
u16 i;
|
||||
|
||||
u8 *ptr8 = (u8 *) src;
|
||||
|
||||
if ((u32) src >= ROM_ADDR && (u32) src < ROM_END_ADDR) {
|
||||
dma_read_s(mem_buff, (u32) src, 512);
|
||||
for (i = 0; i < 512; i++)mem_spi(mem_buff[i]);
|
||||
} else {
|
||||
for (i = 0; i < 512; i++)mem_spi(*ptr8++);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void memSpiBusy() {
|
||||
|
||||
while (evd_isSpiBusy());
|
||||
|
||||
}
|
||||
|
||||
void memRomWrite32(u32 addr, u32 val) {
|
||||
|
||||
vu32 *ptr = (u32 *) (addr + ROM_ADDR);
|
||||
vu8 tmp;
|
||||
|
||||
tmp = *ptr;
|
||||
*ptr = val;
|
||||
tmp = *ptr;
|
||||
}
|
||||
|
||||
u32 memRomRead32(u32 addr) {
|
||||
|
||||
vu32 *ptr = (u32 *) (addr + ROM_ADDR);
|
||||
vu8 tmp;
|
||||
vu32 val;
|
||||
|
||||
tmp = *ptr;
|
||||
val = *ptr;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
u8 mem_spi(u8 dat) {
|
||||
return evd_SPI(dat);
|
||||
}
|
||||
|
||||
*/
|
39
mem.h
Normal file
39
mem.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* File: mem.h
|
||||
* Author: krik
|
||||
*
|
||||
* Created on 2 Èþíü 2011 ã., 4:07
|
||||
*/
|
||||
|
||||
#ifndef _MEM_H
|
||||
#define _MEM_H
|
||||
#include "types.h"
|
||||
|
||||
#define SPI_SPEED_INIT 2
|
||||
#define SPI_SPEED_25 1
|
||||
#define SPI_SPEED_50 0
|
||||
|
||||
#define mem_spi evd_SPI
|
||||
#define memSpiSetSpeed evd_setSpiSpeed
|
||||
#define memSpiIsBusy evd_isSpiBusy
|
||||
#define memSpiSSOff evd_spiSSOff
|
||||
#define memSpiSSOn evd_spiSSOn
|
||||
|
||||
|
||||
void memSpiSSOn();
|
||||
void memSpiSSOff();
|
||||
void memSpiBusy();
|
||||
u8 memSpiIsBusy();
|
||||
void memSpiSetSpeed(u8 speed);
|
||||
void spiReadBlock(void *dat);
|
||||
void spiWriteBlock(void *dat);
|
||||
u8 memSpiRead(void *dst, u16 slen);
|
||||
u8 memSpiWrite(void *src);
|
||||
//u8 mem_spi(u8 dat);
|
||||
void memfill(void *dst, u8 val, u16 len);
|
||||
void memcopy(void *src, void *dst, u16 len);
|
||||
void memSpiSetDma(u8 mode);
|
||||
void memRomWrite32(u32 addr, u32 val);
|
||||
u32 memRomRead32(u32 addr);
|
||||
#endif /* _MEM_H */
|
||||
|
108
menu.h
Normal file
108
menu.h
Normal file
@ -0,0 +1,108 @@
|
||||
//protos maybe some aren't necessary any longer
|
||||
void strhicase(u8 *str, u8 len);
|
||||
void PI_DMAWait(void);
|
||||
void evd_writeReg(u8 reg, u16 val);
|
||||
void bootRom(display_context_t disp, int silent);
|
||||
void loadrom(display_context_t disp, u8 *buff, int fast);
|
||||
void loadgbrom(display_context_t disp, u8 *buff);
|
||||
void view_mpk_file(display_context_t disp, char *mpk_filename);
|
||||
char TranslateNotes( char *bNote, char *Text );
|
||||
inline char CountBlocks( char *bMemPakBinary, char *aNoteSizes );
|
||||
void view_mpk(display_context_t disp);
|
||||
void evd_ulockRegs(void);
|
||||
u8 fatReadCluster(void *dst);
|
||||
u8 fatGetNextCluster(u32 *cluster);
|
||||
u8 fatSkipCluster();
|
||||
void memRomWrite32(u32 addr, u32 val);
|
||||
u32 memRomRead32(u32 addr);
|
||||
uint32_t translate_color(char *hexstring);
|
||||
void evd_init(void);
|
||||
void memSpiSetDma(u8 mode);
|
||||
u16 evd_getFirmVersion(void);
|
||||
u8 evd_isSDMode(void);
|
||||
void dma_write_s(void * ram_address, unsigned long pi_address, unsigned long len);
|
||||
void dma_read_s(void * ram_address, unsigned long pi_address, unsigned long len);
|
||||
void readSDcard(display_context_t disp, char *directory);
|
||||
int readConfigFile(void);
|
||||
//void readCheatFile(display_context_t disp);
|
||||
int readCheatFile(char *filename);
|
||||
static int configHandler(void* user, const char* section, const char* name, const char* value);
|
||||
int saveTypeToSd(display_context_t disp, char* save_filename ,int tpye);
|
||||
int saveTypeFromSd(display_context_t disp, char* rom_name, int stype);
|
||||
int backupSaveData(display_context_t disp);
|
||||
void romInfoScreen(display_context_t disp, u8 *buff, int silent);
|
||||
void checksum_sdram(void);
|
||||
void drawShortInfoBox(display_context_t disp, char* text, u8 mode);
|
||||
void drawToplistSelection(display_context_t disp,int l);
|
||||
//boxes
|
||||
void drawBox(short x, short y, short width, short height, display_context_t disp);
|
||||
void drawBoxNumber(display_context_t disp, int box);
|
||||
|
||||
void printText(char *msg, int x, int y, display_context_t dcon);
|
||||
void lprintText(char *msg, int x, int y, display_context_t dcon);
|
||||
void sleep(unsigned long int ms);
|
||||
void clearScreen(display_context_t disp);
|
||||
|
||||
//mp3
|
||||
void start_mp3(char *fname, long long *samples, int *rate, int *channels);
|
||||
|
||||
//character input functions
|
||||
void drawTextInput(display_context_t disp,char *msg);
|
||||
void drawInputAdd(display_context_t disp, char *msg);
|
||||
void drawInputDel(display_context_t disp);
|
||||
|
||||
void readRomConfig(display_context_t disp, char* short_filename, char* full_filename);
|
||||
void alterRomConfig(int type, int mode);
|
||||
void drawConfigSelection(display_context_t disp,int l);
|
||||
void drawRomConfigBox(display_context_t disp,int line);
|
||||
|
||||
#define MAX_LIST 20
|
||||
#define REG_VER 11
|
||||
#define ED_CFG_SDRAM_ON 0
|
||||
|
||||
#define ishexchar(c) (((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f')))
|
||||
|
||||
|
||||
//debug flag to enable some debug outputs
|
||||
///////////////////////////////////////////
|
||||
#define DBG_MODE 0
|
||||
///////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Return the uncached memory address of a cached address
|
||||
*
|
||||
* @param[in] x
|
||||
* The cached address
|
||||
*uint32_t
|
||||
* @return The uncached address
|
||||
*/
|
||||
#define UNCACHED_ADDR(x) ((void *)(((uint32_t)(x)) | 0xA0000000))
|
||||
|
||||
/**
|
||||
* @brief Align a memory address to 16 byte offset
|
||||
*
|
||||
* @param[in] x
|
||||
* Unaligned memory address
|
||||
*
|
||||
* @return An aligned address guaranteed to be >= the unaligned address
|
||||
*/
|
||||
#define ALIGN_16BYTE(x) ((void *)(((uint32_t)(x)+15) & 0xFFFFFFF0))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
446
mp3.c
Normal file
446
mp3.c
Normal file
@ -0,0 +1,446 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <mad.h>
|
||||
#include "fat.h"
|
||||
|
||||
#include <libdragon.h>
|
||||
|
||||
static struct mad_stream Stream;
|
||||
static struct mad_header Header;
|
||||
static struct mad_frame Frame;
|
||||
static struct mad_synth Synth;
|
||||
static mad_timer_t Timer;
|
||||
|
||||
typedef struct {
|
||||
short left;
|
||||
short right;
|
||||
} Sample;
|
||||
|
||||
static int eos;
|
||||
|
||||
#define INPUT_BUFFER_SIZE 2048
|
||||
static unsigned char fileBuffer[INPUT_BUFFER_SIZE];
|
||||
static unsigned char readBuffer[INPUT_BUFFER_SIZE];
|
||||
static int useReadBuffer;
|
||||
static int readPos;
|
||||
static unsigned int readLen;
|
||||
static int samplesRead;
|
||||
|
||||
char * mp3File;
|
||||
char * mp3Fd;
|
||||
long mp3File_fptr=0;
|
||||
int mp3File_fsize;
|
||||
|
||||
extern int gBrowser;
|
||||
extern char path[1024];
|
||||
|
||||
extern void c2wstrcpy(void *dst, void *src);
|
||||
extern void c2wstrcat(void *dst, void *src);
|
||||
|
||||
|
||||
static int mp3_seek(char* fd, int offset, int whence)
|
||||
{
|
||||
|
||||
//todo filesize and mp3File_fptr;
|
||||
|
||||
|
||||
long offs = 0;
|
||||
// libff routine
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
offs = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
offs = mp3File_fptr + offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
offs = mp3File_fsize + offset;
|
||||
break;
|
||||
}
|
||||
//f_lseek(&mp3File, offs);
|
||||
mp3File_fptr=offs;
|
||||
|
||||
return offs;
|
||||
|
||||
}
|
||||
|
||||
static int mp3_size(char* fd)
|
||||
{
|
||||
FatRecord rec_tmpf;
|
||||
u8 resp=0;
|
||||
resp = fatOpenFileByeName(fd, 0); //err if not found ^^
|
||||
|
||||
int fsize = file.sec_available*512; //fsize in bytes
|
||||
mp3File_fsize = fsize;
|
||||
//todo filesize
|
||||
return mp3File_fsize;
|
||||
|
||||
}
|
||||
|
||||
static void _f_read(char* fname, unsigned char *readBuffer, int size){
|
||||
|
||||
|
||||
/*
|
||||
FatRecord rec_tmpf;
|
||||
u8 resp=0;
|
||||
resp = fatOpenFileByeName(fname, 0); //err if not found ^^
|
||||
|
||||
int fsize = file.sec_available*512; //fsize in bytes
|
||||
mp3File_fsize = fsize;
|
||||
|
||||
|
||||
|
||||
//injecting in buffer... slow but working :/
|
||||
if(file.sec_available*512>=size){
|
||||
resp = fatReadPartialFile(readBuffer, size/512, mp3File_fptr);
|
||||
//resp = fatReadFile(readBuffer+mp3File_fptr, size/512);//file.sec_available);
|
||||
mp3File_fptr+=size;
|
||||
|
||||
}
|
||||
//dma_write_s(buffer, 0xb0000000, fsize);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
static int mp3_read(char* fd, unsigned char *ptr, int size)
|
||||
{
|
||||
int ts=size;
|
||||
_f_read(fd, ptr, size);
|
||||
return ts;
|
||||
|
||||
}
|
||||
|
||||
static int id3_tag_size(unsigned char const *buf, int remaining)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (remaining < 10)
|
||||
return 0;
|
||||
|
||||
if (!strncmp((char*)buf, "ID3", 3) || !strncmp((char*)buf, "ea3", 3)) //skip past id3v2 header, which can cause a false sync to be found
|
||||
{
|
||||
//get the real size from the syncsafe int
|
||||
size = buf[6];
|
||||
size = (size<<7) | buf[7];
|
||||
size = (size<<7) | buf[8];
|
||||
size = (size<<7) | buf[9];
|
||||
|
||||
size += 10;
|
||||
|
||||
if (buf[5] & 0x10) //has footer
|
||||
size += 10;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
//Seek next valid frame after ID3/EA3 header
|
||||
//NOTE: adapted from Music prx 0.55 source
|
||||
// credit goes to joek2100.
|
||||
static int MP3_SkipHdr(char* fd)
|
||||
{
|
||||
int offset = 0;
|
||||
unsigned char buf[1024];
|
||||
unsigned char *pBuffer;
|
||||
int i;
|
||||
int size = 0;
|
||||
|
||||
offset = mp3_seek(fd, 0, SEEK_CUR);
|
||||
mp3_read(fd, buf, sizeof(buf));
|
||||
if (!strncmp((char*)buf, "ID3", 3) || !strncmp((char*)buf, "ea3", 3)) //skip past id3v2 header, which can cause a false sync to be found
|
||||
{
|
||||
//get the real size from the syncsafe int
|
||||
size = buf[6];
|
||||
size = (size<<7) | buf[7];
|
||||
size = (size<<7) | buf[8];
|
||||
size = (size<<7) | buf[9];
|
||||
|
||||
size += 10;
|
||||
|
||||
if (buf[5] & 0x10) //has footer
|
||||
size += 10;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
mp3_seek(fd, offset, SEEK_SET);
|
||||
|
||||
//now seek for a sync
|
||||
while(1)
|
||||
{
|
||||
offset = mp3_seek(fd, 0, SEEK_CUR);
|
||||
size = mp3_read(fd, buf, sizeof(buf));
|
||||
|
||||
if (size <= 2)//at end of file
|
||||
return -1;
|
||||
|
||||
if (!strncmp((char*)buf, "EA3", 3)) //oma mp3 files have non-safe ints in the EA3 header
|
||||
{
|
||||
mp3_seek(fd, (buf[4]<<8)+buf[5], SEEK_CUR);
|
||||
continue;
|
||||
}
|
||||
|
||||
pBuffer = buf;
|
||||
for( i = 0; i < size; i++)
|
||||
{
|
||||
//if this is a valid frame sync (0xe0 is for mpeg version 2.5,2+1)
|
||||
if ( (pBuffer[i] == 0xff) && ((pBuffer[i+1] & 0xE0) == 0xE0) )
|
||||
{
|
||||
offset += i;
|
||||
mp3_seek(fd, offset, SEEK_SET);
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
//go back two bytes to catch any syncs that on the boundary
|
||||
mp3_seek(fd, -2, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
static short convertSample(mad_fixed_t Fixed)
|
||||
{
|
||||
/* Clipping */
|
||||
if (Fixed >= MAD_F_ONE)
|
||||
return (32767);
|
||||
if (Fixed <= -MAD_F_ONE)
|
||||
return (-32768);
|
||||
|
||||
/* Conversion. */
|
||||
Fixed = Fixed >> (MAD_F_FRACBITS - 15);
|
||||
return ((short)Fixed);
|
||||
}
|
||||
|
||||
static int fillFileBuffer()
|
||||
{
|
||||
int leftOver = Stream.bufend - Stream.next_frame;
|
||||
int want = INPUT_BUFFER_SIZE - leftOver;
|
||||
|
||||
// move left-over bytes
|
||||
if (leftOver > 0)
|
||||
memmove(fileBuffer, fileBuffer + want, leftOver);
|
||||
|
||||
// fill remainder of buffer
|
||||
unsigned char* bufferPos = fileBuffer + leftOver;
|
||||
while (want > 0)
|
||||
{
|
||||
int got = mp3_read(mp3Fd, bufferPos, want);
|
||||
if (got <= 0)
|
||||
return 1; // EOF
|
||||
|
||||
want -= got;
|
||||
bufferPos += got;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void decode()
|
||||
{
|
||||
while (mad_frame_decode(&Frame, &Stream) == -1)
|
||||
{
|
||||
if ((Stream.error == MAD_ERROR_BUFLEN) || (Stream.error == MAD_ERROR_BUFPTR))
|
||||
{
|
||||
if (fillFileBuffer())
|
||||
{
|
||||
eos = 1;
|
||||
break;
|
||||
}
|
||||
mad_stream_buffer(&Stream, fileBuffer, INPUT_BUFFER_SIZE);
|
||||
}
|
||||
else if (Stream.error == MAD_ERROR_LOSTSYNC)
|
||||
{
|
||||
/* LOSTSYNC - due to ID3 tags? */
|
||||
int tagsize = id3_tag_size(Stream.this_frame, Stream.bufend - Stream.this_frame);
|
||||
if (tagsize > 0)
|
||||
{
|
||||
mad_stream_skip (&Stream, tagsize);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mad_timer_add(&Timer, Frame.header.duration);
|
||||
mad_synth_frame(&Synth, &Frame);
|
||||
}
|
||||
|
||||
static void convertLeftSamples(Sample* first, Sample* last, const mad_fixed_t* src)
|
||||
{
|
||||
for (Sample *dst = first; dst != last; ++dst)
|
||||
dst->left = convertSample(*src++);
|
||||
}
|
||||
|
||||
static void convertRightSamples(Sample* first, Sample* last, const mad_fixed_t* src)
|
||||
{
|
||||
for (Sample *dst = first; dst != last; ++dst)
|
||||
dst->right = convertSample(*src++);
|
||||
}
|
||||
|
||||
static void MP3_Callback(void *buffer, unsigned int samplesToWrite)
|
||||
{
|
||||
Sample *destination = (Sample*)buffer;
|
||||
|
||||
while (samplesToWrite > 0)
|
||||
{
|
||||
while (!eos && (Synth.pcm.length == 0))
|
||||
decode();
|
||||
|
||||
if (eos)
|
||||
{
|
||||
// done
|
||||
memset(destination, 0, samplesToWrite*4);
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int samplesAvailable = Synth.pcm.length - samplesRead;
|
||||
if (samplesAvailable > samplesToWrite)
|
||||
{
|
||||
convertLeftSamples(destination, destination + samplesToWrite, &Synth.pcm.samples[0][samplesRead]);
|
||||
convertRightSamples(destination, destination + samplesToWrite, &Synth.pcm.samples[1][samplesRead]);
|
||||
|
||||
samplesRead += samplesToWrite;
|
||||
samplesToWrite = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
convertLeftSamples(destination, destination + samplesAvailable, &Synth.pcm.samples[0][samplesRead]);
|
||||
convertRightSamples(destination, destination + samplesAvailable, &Synth.pcm.samples[1][samplesRead]);
|
||||
|
||||
destination += samplesAvailable;
|
||||
samplesToWrite -= samplesAvailable;
|
||||
|
||||
samplesRead = 0;
|
||||
decode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void MP3_Init()
|
||||
{
|
||||
/* First the structures used by libmad must be initialized. */
|
||||
mad_stream_init(&Stream);
|
||||
mad_header_init(&Header);
|
||||
mad_frame_init(&Frame);
|
||||
mad_synth_init(&Synth);
|
||||
mad_timer_reset(&Timer);
|
||||
}
|
||||
|
||||
static void MP3_Exit()
|
||||
{
|
||||
mad_synth_finish(&Synth);
|
||||
mad_header_finish(&Header);
|
||||
mad_frame_finish(&Frame);
|
||||
mad_stream_finish(&Stream);
|
||||
}
|
||||
|
||||
static void MP3_GetInfo(long long *samples, int *rate)
|
||||
{
|
||||
unsigned long FrameCount = 0;
|
||||
int bufferSize = 1024*512;
|
||||
unsigned char *localBuffer;
|
||||
long red = 0;
|
||||
double totalBitrate = 0.0;
|
||||
double mediumBitrate = 0.0;
|
||||
struct mad_stream stream;
|
||||
struct mad_header header;
|
||||
int size = mp3_size(mp3Fd);
|
||||
long count = size;
|
||||
|
||||
mad_stream_init (&stream);
|
||||
mad_header_init (&header);
|
||||
|
||||
localBuffer = (unsigned char *)malloc(bufferSize);
|
||||
|
||||
for (int i=0; i<3; i++)
|
||||
{
|
||||
memset(localBuffer, 0, bufferSize);
|
||||
|
||||
if (count > bufferSize)
|
||||
red = mp3_read(mp3Fd, localBuffer, bufferSize);
|
||||
else
|
||||
red = mp3_read(mp3Fd, localBuffer, count);
|
||||
count -= red;
|
||||
if (!red)
|
||||
break; // ran out of data
|
||||
|
||||
mad_stream_buffer (&stream, localBuffer, red);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (mad_header_decode(&header, &stream) == -1)
|
||||
{
|
||||
if (stream.buffer == NULL || stream.error == MAD_ERROR_BUFLEN)
|
||||
break;
|
||||
else if (MAD_RECOVERABLE(stream.error))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (FrameCount++ == 0)
|
||||
*rate = header.samplerate;
|
||||
totalBitrate += header.bitrate;
|
||||
}
|
||||
}
|
||||
|
||||
mediumBitrate = totalBitrate / (double)FrameCount;
|
||||
int secs = size * 8 / mediumBitrate;
|
||||
*samples = *rate * secs;
|
||||
|
||||
mad_header_finish (&header);
|
||||
mad_stream_finish (&stream);
|
||||
|
||||
if (localBuffer)
|
||||
free(localBuffer);
|
||||
|
||||
mp3_seek(mp3Fd, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
void start_mp3(char *fname, long long *samples, int *rate, int *channels)
|
||||
{
|
||||
|
||||
sprintf(mp3Fd, "%s", fname);
|
||||
|
||||
|
||||
//if (mp3Fd[0]!=0)
|
||||
//{
|
||||
useReadBuffer = 0;
|
||||
MP3_GetInfo(samples, rate);
|
||||
*channels = 2;
|
||||
|
||||
MP3_Init();
|
||||
MP3_SkipHdr(mp3Fd);
|
||||
eos = readLen = readPos = 0;
|
||||
useReadBuffer = 1;
|
||||
return;
|
||||
//}
|
||||
|
||||
//*samples = 0;
|
||||
//return;
|
||||
}
|
||||
|
||||
void stop_mp3(void)
|
||||
{
|
||||
MP3_Exit();
|
||||
mp3File_fptr=0;
|
||||
/*
|
||||
if (mp3Fd > 0)
|
||||
{
|
||||
if (gBrowser)
|
||||
f_close(&mp3File);
|
||||
else
|
||||
dfs_close(mp3Fd);
|
||||
}
|
||||
mp3Fd = -1;
|
||||
*/
|
||||
}
|
||||
|
||||
int update_mp3(char *buf, int bytes)
|
||||
{
|
||||
MP3_Callback(buf, bytes/4);
|
||||
return eos ? 0 : 1;
|
||||
}
|
127
sram.c
Normal file
127
sram.c
Normal file
@ -0,0 +1,127 @@
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "sys.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "sram.h"
|
||||
|
||||
|
||||
void PI_Init(void) {
|
||||
PI_DMAWait();
|
||||
IO_WRITE(PI_STATUS_REG, 0x03);
|
||||
}
|
||||
|
||||
// Inits PI for sram transfer
|
||||
void PI_Init_SRAM(void) {
|
||||
|
||||
|
||||
IO_WRITE(PI_BSD_DOM2_LAT_REG, 0x05);
|
||||
IO_WRITE(PI_BSD_DOM2_PWD_REG, 0x0C);
|
||||
IO_WRITE(PI_BSD_DOM2_PGS_REG, 0x0D);
|
||||
IO_WRITE(PI_BSD_DOM2_RLS_REG, 0x02);
|
||||
|
||||
}
|
||||
|
||||
void PI_DMAWait(void) {
|
||||
|
||||
|
||||
/*PI DMA wait
|
||||
|
||||
1. Read PI_STATUS_REG then AND it with 0x3, if its true... then wait until
|
||||
it is not true.
|
||||
*/
|
||||
|
||||
while (IO_READ(PI_STATUS_REG) & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY));
|
||||
}
|
||||
|
||||
|
||||
void PI_DMAFromSRAM(void *dest, u32 offset, u32 size) {
|
||||
|
||||
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
|
||||
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
|
||||
asm volatile ("" : : : "memory");
|
||||
IO_WRITE(PI_WR_LEN_REG, (size - 1));
|
||||
asm volatile ("" : : : "memory");
|
||||
|
||||
|
||||
/*
|
||||
PI_DMAWait();
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 0x03);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
|
||||
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
|
||||
_data_cache_invalidate_all();
|
||||
IO_WRITE(PI_WR_LEN_REG, (size - 1));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void PI_DMAToSRAM(void *src, u32 offset, u32 size) { //void*
|
||||
PI_DMAWait();
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 2);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(src));
|
||||
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
|
||||
_data_cache_invalidate_all();
|
||||
//data_cache_hit_writeback_invalidate(src,size);
|
||||
|
||||
/* Write back . nusys - only writeback
|
||||
osWritebackDCache((void*)buf_ptr, (s32)size);
|
||||
*/
|
||||
//libdragon equivalent
|
||||
// data_cache_hit_writeback (src, size);
|
||||
|
||||
IO_WRITE(PI_RD_LEN_REG, (size - 1));
|
||||
}
|
||||
|
||||
void PI_DMAFromCart(void* dest, void* src, u32 size) {
|
||||
PI_DMAWait();
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 0x03);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
|
||||
IO_WRITE(PI_CART_ADDR_REG, K0_TO_PHYS(src));
|
||||
//_data_cache_invalidate_all();
|
||||
IO_WRITE(PI_WR_LEN_REG, (size - 1));
|
||||
}
|
||||
|
||||
|
||||
void PI_DMAToCart(void* dest, void* src, u32 size) {
|
||||
PI_DMAWait();
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 0x02);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(src));
|
||||
IO_WRITE(PI_CART_ADDR_REG, K0_TO_PHYS(dest));
|
||||
//_data_cache_invalidate_all();
|
||||
IO_WRITE(PI_RD_LEN_REG, (size - 1));
|
||||
}
|
||||
|
||||
|
||||
// Wrapper to support unaligned access to memory
|
||||
void PI_SafeDMAFromCart(void *dest, void *src, u32 size) {
|
||||
if (!dest || !src || !size) return;
|
||||
|
||||
u32 unalignedSrc = ((u32)src) % 2;
|
||||
u32 unalignedDest = ((u32)dest) % 8;
|
||||
|
||||
//FIXME: Do i really need to check if size is 16bit aligned?
|
||||
if (!unalignedDest && !unalignedSrc && !(size % 2)) {
|
||||
PI_DMAFromCart(dest, src, size);
|
||||
PI_DMAWait();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void* newSrc = (void*)(((u32)src) - unalignedSrc);
|
||||
u32 newSize = (size + unalignedSrc) + ((size + unalignedSrc) % 2);
|
||||
|
||||
u8 *buffer = memalign(8, newSize);
|
||||
PI_DMAFromCart(buffer, newSrc, newSize);
|
||||
PI_DMAWait();
|
||||
|
||||
memcpy(dest, (buffer + unalignedSrc), size);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
32
sram.h
Normal file
32
sram.h
Normal file
@ -0,0 +1,32 @@
|
||||
//sram.h
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "types.h"
|
||||
|
||||
void data_cache_hit_writeback_invalidate(volatile void *, unsigned long);
|
||||
unsigned int CRC_Calculate(unsigned int crc, unsigned char* buf, unsigned int len);
|
||||
void dma_write_sram(void* src, u32 offset, u32 size);
|
||||
void dma_read_sram(void *dest, u32 offset, u32 size);
|
||||
void dma_write_s(void * ram_address, unsigned long pi_address, unsigned long len);
|
||||
void dma_read_s(void * ram_address, unsigned long pi_address, unsigned long len);
|
||||
int writeSram(void* src, u32 size);
|
||||
void setSDTiming(void);
|
||||
|
||||
|
||||
void PI_Init(void);
|
||||
void PI_Init_SRAM(void);
|
||||
void PI_DMAWait(void);
|
||||
void PI_DMAFromCart(void* dest, void* src, u32 size);
|
||||
void PI_DMAToCart(void* dest, void* src, u32 size);
|
||||
void PI_DMAFromSRAM(void *dest, u32 offset, u32 size);
|
||||
void PI_DMAToSRAM(void* src, u32 offset, u32 size);
|
||||
void PI_SafeDMAFromCart(void *dest, void *src, u32 size);
|
||||
|
||||
//memory
|
||||
/*** MEMORY ***/
|
||||
void *safe_memalign(size_t boundary, size_t size);
|
||||
void *safe_calloc(size_t nmemb, size_t size);
|
||||
void *safe_malloc(size_t size);
|
||||
void safe_free(void *ptr);
|
||||
void *safe_memset(void *s, int c, size_t n);
|
||||
void *safe_memcpy(void *dest, const void *src, size_t n);
|
4940
stb_image.c
Normal file
4940
stb_image.c
Normal file
File diff suppressed because it is too large
Load Diff
1807
stb_truetype.h
Normal file
1807
stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
43
strlib.c
Normal file
43
strlib.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include "strlib.h"
|
||||
|
||||
char *strcpytrim(char *d, // destination
|
||||
char *s, // source
|
||||
int mode,
|
||||
char *delim
|
||||
) {
|
||||
char *o = d; // save orig
|
||||
char *e = 0; // end space ptr.
|
||||
char dtab[256] = {0};
|
||||
if (!s || !d) return 0;
|
||||
|
||||
if (!delim) delim = " \t\n\f";
|
||||
while (*delim)
|
||||
dtab[*delim++] = 1;
|
||||
|
||||
while ( (*d = *s++) != 0 ) {
|
||||
if (!dtab[*d]) { // Not a match char
|
||||
e = 0; // Reset end pointer
|
||||
} else {
|
||||
if (!e) e = d; // Found first match.
|
||||
|
||||
if ( mode == STRLIB_MODE_ALL || ((mode != STRLIB_MODE_RIGHT) && (d == o)) )
|
||||
continue;
|
||||
}
|
||||
d++;
|
||||
}
|
||||
if (mode != STRLIB_MODE_LEFT && e) { // for everything but trim_left, delete trailing matches.
|
||||
*e = 0;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// perhaps these could be inlined in strlib.h
|
||||
char *strtriml(char *d, char *s) { return strcpytrim(d, s, STRLIB_MODE_LEFT, 0); }
|
||||
char *strtrimr(char *d, char *s) { return strcpytrim(d, s, STRLIB_MODE_RIGHT, 0); }
|
||||
char *strtrim(char *d, char *s) { return strcpytrim(d, s, STRLIB_MODE_BOTH, 0); }
|
||||
char *strstrlibkill(char *d, char *s) { return strcpytrim(d, s, STRLIB_MODE_ALL, 0); }
|
||||
|
||||
char *triml(char *s) { return strcpytrim(s, s, STRLIB_MODE_LEFT, 0); }
|
||||
char *trimr(char *s) { return strcpytrim(s, s, STRLIB_MODE_RIGHT, 0); }
|
||||
char *trim(char *s) { return strcpytrim(s, s, STRLIB_MODE_BOTH, 0); }
|
||||
char *strlibkill(char *s) { return strcpytrim(s, s, STRLIB_MODE_ALL, 0); }
|
24
strlib.h
Normal file
24
strlib.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef STRLIB_H_
|
||||
enum strtrim_mode_t {
|
||||
STRLIB_MODE_ALL = 0,
|
||||
STRLIB_MODE_RIGHT = 0x01,
|
||||
STRLIB_MODE_LEFT = 0x02,
|
||||
STRLIB_MODE_BOTH = 0x03
|
||||
};
|
||||
|
||||
char *strcpytrim(char *d, // destination
|
||||
char *s, // source
|
||||
int mode,
|
||||
char *delim
|
||||
);
|
||||
|
||||
char *strtriml(char *d, char *s);
|
||||
char *strtrimr(char *d, char *s);
|
||||
char *strtrim(char *d, char *s);
|
||||
char *strstrlibkill(char *d, char *s);
|
||||
|
||||
char *triml(char *s);
|
||||
char *trimr(char *s);
|
||||
char *trim(char *s);
|
||||
char *strlibkill(char *s);
|
||||
#endif
|
359
sys.c
Normal file
359
sys.c
Normal file
@ -0,0 +1,359 @@
|
||||
#include <stdint.h>
|
||||
#include <dma.h>
|
||||
#include <n64sys.h>
|
||||
#include "sys.h"
|
||||
#include "types.h"
|
||||
#include "everdrive.h"
|
||||
#include "errors.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
u32 asm_date;
|
||||
|
||||
Options_st options;
|
||||
|
||||
u32 native_tv_mode;
|
||||
|
||||
#define CIC_6101 1
|
||||
#define CIC_6102 2
|
||||
#define CIC_6103 3
|
||||
#define CIC_6104 4
|
||||
#define CIC_6105 5
|
||||
#define CIC_6106 6
|
||||
|
||||
u16 strcon(u8 *str1, u8 *str2, u8 *dst, u16 max_len) {
|
||||
|
||||
u16 len = 0;
|
||||
max_len -= 1;
|
||||
|
||||
while (*str1 != 0 && len < max_len) {
|
||||
*dst++ = *str1++;
|
||||
len++;
|
||||
}
|
||||
|
||||
while (*str2 != 0 && len < max_len) {
|
||||
*dst++ = *str2++;
|
||||
len++;
|
||||
}
|
||||
*dst++ = 0;
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void dma_read_s(void * ram_address, unsigned long pi_address, unsigned long len) {
|
||||
|
||||
u32 buff[256];
|
||||
|
||||
u32 *bptr;
|
||||
|
||||
u32 *rptr = (u32 *) ram_address;
|
||||
|
||||
// if(len==32768)
|
||||
// rptr = (u32 *) 0x803F7988;
|
||||
|
||||
u16 i;
|
||||
|
||||
//u16 blen = 512;
|
||||
//if (len < 512)blen = len;
|
||||
//*(volatile u32*) 0x1FC007FC = 0x08;
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 3);
|
||||
while (len) {
|
||||
dma_read(buff, pi_address, 512);
|
||||
while ((IO_READ(PI_STATUS_REG) & 3) != 0);
|
||||
//while ((*((volatile u32*) PI_STATUS_REG) & 0x02) != 1);
|
||||
data_cache_hit_invalidate(buff, 512);
|
||||
bptr = buff;
|
||||
for (i = 0; i < 512 && i < len; i += 4)*rptr++ = *bptr++;
|
||||
len = len < 512 ? 0 : len - 512;
|
||||
pi_address += 512;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_write_s(void * ram_address, unsigned long pi_address, unsigned long len) {
|
||||
|
||||
|
||||
//if(len==32768)
|
||||
//ram_address = (u32 *) 0x803F7988;
|
||||
|
||||
|
||||
data_cache_hit_writeback(ram_address, len);
|
||||
dma_write(ram_address, pi_address, len);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void showError(char *str, u32 code) {
|
||||
|
||||
|
||||
console_printf("%s%u\n", str, code);
|
||||
joyWait();
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
void sleep(u32 ms) {
|
||||
|
||||
u32 current_ms = get_ticks_ms();
|
||||
|
||||
while (get_ticks_ms() - current_ms < ms);
|
||||
|
||||
}
|
||||
|
||||
void dma_read_sram(void *dest, u32 offset, u32 size) {
|
||||
/*
|
||||
PI_DMAWait();
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 0x03);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
|
||||
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
|
||||
// data_cache_invalidate_all();
|
||||
IO_WRITE(PI_WR_LEN_REG, (size - 1));
|
||||
*/
|
||||
/* 0xA8000000
|
||||
* 0xb0000000
|
||||
* 0x4000000
|
||||
* */
|
||||
dma_read_s(dest, 0xA8000000 + offset, size);
|
||||
//data_cache_invalidate(dest,size);
|
||||
|
||||
}
|
||||
|
||||
void dma_write_sram(void* src, u32 offset, u32 size) {
|
||||
/*
|
||||
PI_DMAWait();
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, 0x02);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(src));
|
||||
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
|
||||
// data_cache_invalidate_all();
|
||||
IO_WRITE(PI_RD_LEN_REG, (size - 1));
|
||||
*/
|
||||
dma_write_s(src, 0xA8000000 + offset, size);
|
||||
|
||||
}
|
||||
|
||||
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
#define DO2(buf) DO1(buf); DO1(buf);
|
||||
#define DO4(buf) DO2(buf); DO2(buf);
|
||||
#define DO8(buf) DO4(buf); DO4(buf);
|
||||
|
||||
unsigned int CRC_Calculate(unsigned int crc, unsigned char* buf, unsigned int len) {
|
||||
static unsigned int crc_table[256];
|
||||
static int make_crc_table = 1;
|
||||
|
||||
if (make_crc_table) {
|
||||
unsigned int c, n;
|
||||
int k;
|
||||
unsigned int poly;
|
||||
const unsigned char p[] = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26};
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320L) */
|
||||
poly = 0L;
|
||||
for (n = 0; n < sizeof (p) / sizeof (unsigned char); n++)
|
||||
poly |= 1L << (31 - p[n]);
|
||||
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[n] = c;
|
||||
}
|
||||
make_crc_table = 0;
|
||||
}
|
||||
|
||||
if (buf == (void*) 0) return 0L;
|
||||
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len >= 8) {
|
||||
DO8(buf);
|
||||
len -= 8;
|
||||
}
|
||||
if (len)
|
||||
do {
|
||||
DO1(buf);
|
||||
} while (--len);
|
||||
|
||||
return crc ^ 0xffffffffL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u32 ii;
|
||||
volatile u32 *pt;
|
||||
void clean();
|
||||
|
||||
#define MEM32(addr) *((volatile u32 *)addr)
|
||||
|
||||
|
||||
u8 str_buff[128];
|
||||
|
||||
u8 STR_intToDecString(u32 val, u8 *str) {
|
||||
|
||||
int len;
|
||||
|
||||
if (val < 10)len = 1;
|
||||
else
|
||||
if (val < 100)len = 2;
|
||||
else
|
||||
if (val < 1000)len = 3;
|
||||
else
|
||||
if (val < 10000)len = 4;
|
||||
else
|
||||
if (val < 100000)len = 5;
|
||||
else
|
||||
if (val < 1000000)len = 6;
|
||||
else
|
||||
if (val < 10000000)len = 7;
|
||||
else
|
||||
if (val < 100000000)len = 8;
|
||||
else
|
||||
if (val < 1000000000)len = 9;
|
||||
else len = 10;
|
||||
|
||||
str += len;
|
||||
str[0] = 0;
|
||||
if (val == 0)*--str = '0';
|
||||
while (val) {
|
||||
|
||||
*--str = '0' + val % 10;
|
||||
val /= 10;
|
||||
}
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void STR_intToDecStringMin(u32 val, u8 *str, u8 min_size) {
|
||||
|
||||
int len;
|
||||
u8 i;
|
||||
|
||||
if (val < 10)len = 1;
|
||||
else
|
||||
if (val < 100)len = 2;
|
||||
else
|
||||
if (val < 1000)len = 3;
|
||||
else
|
||||
if (val < 10000)len = 4;
|
||||
else
|
||||
if (val < 100000)len = 5;
|
||||
else
|
||||
if (val < 1000000)len = 6;
|
||||
else
|
||||
if (val < 10000000)len = 7;
|
||||
else
|
||||
if (val < 100000000)len = 8;
|
||||
else
|
||||
if (val < 1000000000)len = 9;
|
||||
else len = 10;
|
||||
|
||||
if (len < min_size) {
|
||||
|
||||
i = min_size - len;
|
||||
while (i--)str[i] = '0';
|
||||
len = min_size;
|
||||
}
|
||||
str += len;
|
||||
str[0] = 0;
|
||||
if (val == 0)*--str = '0';
|
||||
while (val) {
|
||||
|
||||
*--str = '0' + val % 10;
|
||||
val /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u8 streq(u8 *str1, u8 *str2) {
|
||||
|
||||
u8 s1;
|
||||
u8 s2;
|
||||
|
||||
for (;;) {
|
||||
s1 = *str1++;
|
||||
s2 = *str2++;
|
||||
if (s1 >= 'a' && s1 <= 'z')s1 -= 0x20;
|
||||
if (s2 >= 'a' && s2 <= 'z')s2 -= 0x20;
|
||||
|
||||
if (s1 != s2) return 0;
|
||||
|
||||
if (*str1 == 0 && *str2 == 0)return 1;
|
||||
}
|
||||
}
|
||||
|
||||
u8 streql(u8 *str1, u8 *str2, u8 len) {
|
||||
|
||||
u8 s1;
|
||||
u8 s2;
|
||||
while (len--) {
|
||||
|
||||
s1 = *str1++;
|
||||
s2 = *str2++;
|
||||
if (s1 >= 'a' && s1 <= 'z')s1 -= 0x20;
|
||||
if (s2 >= 'a' && s2 <= 'z')s2 -= 0x20;
|
||||
|
||||
if (s1 != s2) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u16 strContain(u8 *target, u8 *str) {
|
||||
|
||||
u16 targ_len = slen(target);
|
||||
u16 eq_len;
|
||||
|
||||
|
||||
for (eq_len = 0; eq_len < targ_len;) {
|
||||
|
||||
if (*str == 0)return 0;
|
||||
if (*str++ == target[eq_len]) {
|
||||
eq_len++;
|
||||
} else {
|
||||
eq_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (eq_len != targ_len)return 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
u8 slen(u8 *str) {
|
||||
|
||||
u8 len = 0;
|
||||
while (*str++)len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
u8 scopy(u8 *src, u8 *dst) {
|
||||
|
||||
u8 len = 0;
|
||||
while (*src != 0) {
|
||||
*dst++ = *src++;
|
||||
len++;
|
||||
}
|
||||
*dst = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
void strhicase(u8 *str, u8 len) {
|
||||
|
||||
if (len) {
|
||||
while (len--) {
|
||||
if (*str >= 'a' && *str <= 'z')*str -= 0x20;
|
||||
str++;
|
||||
}
|
||||
} else {
|
||||
while (*str != 0) {
|
||||
if (*str >= 'a' && *str <= 'z')*str -= 0x20;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
61
sys.h
Normal file
61
sys.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* File: tools.h
|
||||
* Author: KRIK
|
||||
*
|
||||
* Created on 16 Àïðåëü 2011 ã., 2:30
|
||||
*/
|
||||
|
||||
#ifndef _SYS_H
|
||||
#define _SYS_H
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include <libdragon.h>
|
||||
|
||||
|
||||
void dma_read_s(void * ram_address, unsigned long pi_address, unsigned long len);
|
||||
void dma_write_s(void * ram_address, unsigned long pi_address, unsigned long len);
|
||||
|
||||
|
||||
void sleep(u32 ms);
|
||||
void dma_write_sram(void* src, u32 offset, u32 size);
|
||||
void dma_read_sram(void *dest, u32 offset, u32 size);
|
||||
u8 getSaveType();
|
||||
u8 getCicType(u8 bios_cic);
|
||||
|
||||
u16 strcon(u8 *str1, u8 *str2, u8 *dst, u16 max_len);
|
||||
u8 slen(u8 *str);
|
||||
u8 scopy(u8 *src, u8 *dst);
|
||||
|
||||
u16 strContain(u8 *target, u8 *str);
|
||||
|
||||
typedef struct SP_regs_s {
|
||||
u32 mem_addr;
|
||||
u32 dram_addr;
|
||||
u32 rd_len;
|
||||
u32 wr_len;
|
||||
u32 status;
|
||||
} _SP_regs_s;
|
||||
|
||||
#define SP_PC *((volatile u32 *)0xA4080000)
|
||||
#define SP_IBIST_REG *((volatile u32 *)0xA4080004)
|
||||
|
||||
static volatile struct AI_regs_s * const AI_regs = (struct AI_regs_s *) 0xa4500000;
|
||||
static volatile struct MI_regs_s * const MI_regs = (struct MI_regs_s *) 0xa4300000;
|
||||
static volatile struct VI_regs_s * const VI_regs = (struct VI_regs_s *) 0xa4400000;
|
||||
static volatile struct PI_regs_s * const PI_regs = (struct PI_regs_s *) 0xa4600000;
|
||||
static volatile struct SP_regs_s * const SP_regs = (struct SP_regs_s *) 0xA4040000;
|
||||
|
||||
extern u32 native_tv_mode;
|
||||
|
||||
typedef struct {
|
||||
u16 sd_speed;
|
||||
u16 font_size;
|
||||
u16 tv_mode;
|
||||
u8 wall[256];
|
||||
} Options_st;
|
||||
|
||||
|
||||
extern Options_st options;
|
||||
extern u32 asm_date;
|
||||
#endif /* _TOOLS_H */
|
||||
|
36
types.h
Normal file
36
types.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* File: types.h
|
||||
* Author: KRIK
|
||||
*
|
||||
* Created on 16 Àïðåëü 2011 ã., 2:24
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
#define u8 unsigned char
|
||||
#define u16 unsigned short
|
||||
#define u32 unsigned long
|
||||
#define u64 unsigned long long
|
||||
|
||||
#define vu8 volatile unsigned char
|
||||
#define vu16 volatile unsigned short
|
||||
#define vu32 volatile unsigned long
|
||||
#define vu64 volatile unsigned long long
|
||||
|
||||
#define s8 signed char
|
||||
#define s16 short
|
||||
#define s32 long
|
||||
#define s64 long long
|
||||
|
||||
|
||||
typedef volatile uint64_t sim_vu64;
|
||||
typedef volatile uint64_t sim_vu64;
|
||||
typedef unsigned int sim_u32;
|
||||
typedef uint64_t sim_u64;
|
||||
|
||||
|
||||
#endif /* _TYPES_H */
|
||||
|
15
upload.sh
Executable file
15
upload.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#! /bin/bash
|
||||
sudo mount /dev/sdb1 /mnt
|
||||
file=/mnt/ED64/OS64.v64
|
||||
if [ -e $file ]
|
||||
then
|
||||
echo -e "File $file exists - mount ok"
|
||||
echo -e "copy..."
|
||||
sudo cp OS64.v64 /mnt/ED64/
|
||||
sudo cp ALT64.INI /mnt/ED64/
|
||||
echo -e "umounting..."
|
||||
sudo umount /mnt
|
||||
echo -e "done..."
|
||||
else
|
||||
echo -e "File $file doesnt exists - sdcard problem?"
|
||||
fi
|
180
usb.c
Normal file
180
usb.c
Normal file
@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
#include "everdrive.h"
|
||||
#include "sys.h"
|
||||
#include "types.h"
|
||||
#include <libdragon.h>
|
||||
#include "rom.h"
|
||||
|
||||
u8 cmdTest();
|
||||
u8 cmdFill();
|
||||
u8 cmdReadRom();
|
||||
u8 cmdWriteRom();
|
||||
|
||||
u64 usb_buff[128];
|
||||
u8 *usb_buff8; // = (u8 *) usb_buff;
|
||||
|
||||
|
||||
#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG+0x14)
|
||||
|
||||
/* PI dom1 pulse width (R/W): [7:0] domain 1 device R/W strobe pulse width */
|
||||
#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG+0x18)
|
||||
|
||||
/* PI dom1 page size (R/W): [3:0] domain 1 device page size */
|
||||
#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG+0x1C) /* page size */
|
||||
|
||||
/* PI dom1 release (R/W): [1:0] domain 1 device R/W release duration */
|
||||
#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG+0x20)
|
||||
/* PI dom2 latency (R/W): [7:0] domain 2 device latency */
|
||||
#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG+0x24) /* Domain 2 latency */
|
||||
|
||||
/* PI dom2 pulse width (R/W): [7:0] domain 2 device R/W strobe pulse width */
|
||||
#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG+0x28) /* pulse width */
|
||||
|
||||
/* PI dom2 page size (R/W): [3:0] domain 2 device page size */
|
||||
#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG+0x2C) /* page size */
|
||||
|
||||
/* PI dom2 release (R/W): [1:0] domain 2 device R/W release duration */
|
||||
#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG+0x30) /* release duration */
|
||||
|
||||
#define PHYS_TO_K1(x) ((u32)(x)|0xA0000000) /* physical to kseg1 */
|
||||
#define IO_WRITE(addr,data) (*(volatile u32*)PHYS_TO_K1(addr)=(u32)(data))
|
||||
#define PI_BASE_REG 0x04600000
|
||||
|
||||
extern u8 system_cic;
|
||||
|
||||
u8 usbListener() {
|
||||
|
||||
volatile u16 resp;
|
||||
volatile u8 cmd;
|
||||
usb_buff8 = (u8 *) usb_buff;
|
||||
|
||||
|
||||
if (evd_fifoRxf())return 0;
|
||||
|
||||
resp = evd_fifoRd(usb_buff, 1);
|
||||
|
||||
if (resp != 0) return 1;
|
||||
|
||||
if (usb_buff8[0] != 'C' || usb_buff8[1] != 'M' || usb_buff8[2] != 'D')return 2;
|
||||
|
||||
cmd = usb_buff8[3];
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case 'R':
|
||||
resp = cmdReadRom();
|
||||
if (resp)return 10;
|
||||
break;
|
||||
case 'W':
|
||||
resp = cmdWriteRom();
|
||||
if (resp)return 11;
|
||||
break;
|
||||
case 'T':
|
||||
resp = cmdTest();
|
||||
if (resp)return 12;
|
||||
break;
|
||||
case 'F':
|
||||
resp = cmdFill();
|
||||
if (resp)return 13;
|
||||
break;
|
||||
case 'S':
|
||||
//IO_WRITE(PI_BSD_DOM1_PGS_REG, 0x0c);
|
||||
//IO_WRITE(PI_BSD_DOM1_PGS_REG, 0x80);
|
||||
//evdSetESaveType(SAVE_TYPE_EEP16k);
|
||||
system_cic = CIC_6102;
|
||||
evd_lockRegs();
|
||||
IO_WRITE(PI_STATUS_REG, 3);
|
||||
sleep(2);
|
||||
pif_boot();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 cmdTest() {
|
||||
|
||||
u16 resp;
|
||||
usb_buff8[3] = 'k';
|
||||
resp = evd_fifoWr(usb_buff, 1);
|
||||
if (resp)return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
u8 cmdFill() {
|
||||
|
||||
u16 resp;
|
||||
u32 i;
|
||||
//console_printf("fill...\n");
|
||||
|
||||
for (i = 0; i < 512; i++) {
|
||||
usb_buff8[i] = 0;
|
||||
}
|
||||
//console_printf("buff prepared\n");
|
||||
romFill(0, 0x200000, 0);
|
||||
//console_printf("fill done\n");
|
||||
|
||||
usb_buff8[3] = 'k';
|
||||
resp = evd_fifoWr(usb_buff, 1);
|
||||
|
||||
if (resp)return 1;
|
||||
//console_printf("resp sent ok\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 cmdReadRom() {
|
||||
|
||||
u16 resp;
|
||||
u16 ptr;
|
||||
u16 len;
|
||||
u32 addr;
|
||||
ptr = 4;
|
||||
|
||||
|
||||
addr = usb_buff8[ptr++];
|
||||
addr <<= 8;
|
||||
addr |= usb_buff8[ptr++];
|
||||
addr *= 2048;
|
||||
|
||||
len = usb_buff8[ptr++];
|
||||
len <<= 8;
|
||||
len |= usb_buff8[ptr++];
|
||||
|
||||
|
||||
resp = evd_fifoWrFromCart(addr, len);
|
||||
if (resp)return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 cmdWriteRom() {
|
||||
|
||||
u16 resp;
|
||||
u16 ptr;
|
||||
u16 len;
|
||||
u32 addr;
|
||||
ptr = 4;
|
||||
|
||||
addr = usb_buff8[ptr++];
|
||||
addr <<= 8;
|
||||
addr |= usb_buff8[ptr++];
|
||||
addr *= 2048;
|
||||
|
||||
len = usb_buff8[ptr++];
|
||||
len <<= 8;
|
||||
len |= usb_buff8[ptr++];
|
||||
|
||||
resp = evd_fifoRdToCart(addr, len);
|
||||
if (resp)return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
16
usb.h
Normal file
16
usb.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* File: fifo.h
|
||||
* Author: KRIK
|
||||
*
|
||||
* Created on 22 Àïðåëü 2011 ã., 20:46
|
||||
*/
|
||||
|
||||
#ifndef _FIFO_H
|
||||
#define _FIFO_H
|
||||
|
||||
#include "types.h"
|
||||
u8 usbListener();
|
||||
|
||||
|
||||
#endif /* _FIFO_H */
|
||||
|
170
utils.h
Normal file
170
utils.h
Normal file
@ -0,0 +1,170 @@
|
||||
// rom.h
|
||||
// rom tools - header inspect
|
||||
#include <stdint.h>
|
||||
#include <libdragon.h>
|
||||
|
||||
/*
|
||||
*
|
||||
|
||||
0000h (1 byte): initial PI_BSB_DOM1_LAT_REG value (0x80)
|
||||
0001h (1 byte): initial PI_BSB_DOM1_PGS_REG value (0x37)
|
||||
0002h (1 byte): initial PI_BSB_DOM1_PWD_REG value (0x12)
|
||||
0003h (1 byte): initial PI_BSB_DOM1_PGS_REG value (0x40)
|
||||
0004h - 0007h (1 dword): ClockRate
|
||||
0008h - 000Bh (1 dword): Program Counter (PC)
|
||||
000Ch - 000Fh (1 dword): Release
|
||||
0010h - 0013h (1 dword): CRC1
|
||||
0014h - 0017h (1 dword): CRC2
|
||||
0018h - 001Fh (2 dwords): Unknown (0x0000000000000000)
|
||||
0020h - 0033h (20 bytes): Image name
|
||||
Padded with 0x00 or spaces (0x20)
|
||||
0034h - 0037h (1 dword): Unknown (0x00000000)
|
||||
0038h - 003Bh (1 dword): Manufacturer ID
|
||||
0x0000004E = Nintendo ('N')
|
||||
003Ch - 003Dh (1 word): Cartridge ID
|
||||
003Eh - 003Fh (1 word): Country code
|
||||
0x4400 = Germany ('D')
|
||||
0x4500 = USA ('E')
|
||||
0x4A00 = Japan ('J')
|
||||
0x5000 = Europe ('P')
|
||||
0x5500 = Australia ('U')
|
||||
0040h - 0FFFh (1008 dwords): Boot code
|
||||
*/
|
||||
|
||||
#define PI_BASE_REG 0x04600000
|
||||
#define PIF_RAM_START 0x1FC007C0
|
||||
|
||||
|
||||
/*
|
||||
* PI status register has 3 bits active when read from (PI_STATUS_REG - read)
|
||||
* Bit 0: DMA busy - set when DMA is in progress
|
||||
* Bit 1: IO busy - set when IO is in progress
|
||||
* Bit 2: Error - set when CPU issues IO request while DMA is busy
|
||||
*/
|
||||
|
||||
#define PI_STATUS_REG (PI_BASE_REG+0x10)
|
||||
|
||||
/* PI DRAM address (R/W): starting RDRAM address */
|
||||
#define PI_DRAM_ADDR_REG (PI_BASE_REG+0x00) /* DRAM address */
|
||||
|
||||
/* PI pbus (cartridge) address (R/W): starting AD16 address */
|
||||
#define PI_CART_ADDR_REG (PI_BASE_REG+0x04)
|
||||
|
||||
/* PI read length (R/W): read data length */
|
||||
#define PI_RD_LEN_REG (PI_BASE_REG+0x08)
|
||||
|
||||
/* PI write length (R/W): write data length */
|
||||
#define PI_WR_LEN_REG (PI_BASE_REG+0x0C)
|
||||
|
||||
/*
|
||||
* PI status (R): [0] DMA busy, [1] IO busy, [2], error
|
||||
* (W): [0] reset controller (and abort current op), [1] clear intr
|
||||
*/
|
||||
|
||||
#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG+0x14)
|
||||
|
||||
/* PI dom1 pulse width (R/W): [7:0] domain 1 device R/W strobe pulse width */
|
||||
#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG+0x18)
|
||||
|
||||
/* PI dom1 page size (R/W): [3:0] domain 1 device page size */
|
||||
#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG+0x1C) /* page size */
|
||||
|
||||
/* PI dom1 release (R/W): [1:0] domain 1 device R/W release duration */
|
||||
#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG+0x20)
|
||||
/* PI dom2 latency (R/W): [7:0] domain 2 device latency */
|
||||
#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG+0x24) /* Domain 2 latency */
|
||||
|
||||
/* PI dom2 pulse width (R/W): [7:0] domain 2 device R/W strobe pulse width */
|
||||
#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG+0x28) /* pulse width */
|
||||
|
||||
/* PI dom2 page size (R/W): [3:0] domain 2 device page size */
|
||||
#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG+0x2C) /* page size */
|
||||
|
||||
/* PI dom2 release (R/W): [1:0] domain 2 device R/W release duration */
|
||||
#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG+0x30) /* release duration */
|
||||
|
||||
|
||||
#define PI_DOMAIN1_REG PI_BSD_DOM1_LAT_REG
|
||||
#define PI_DOMAIN2_REG PI_BSD_DOM2_LAT_REG
|
||||
|
||||
|
||||
#define PI_STATUS_ERROR 0x04
|
||||
#define PI_STATUS_IO_BUSY 0x02
|
||||
#define PI_STATUS_DMA_BUSY 0x01
|
||||
|
||||
#define PHYS_TO_K0(x) ((u32)(x)|0x80000000) /* physical to kseg0 */
|
||||
#define K0_TO_PHYS(x) ((u32)(x)&0x1FFFFFFF) /* kseg0 to physical */
|
||||
#define PHYS_TO_K1(x) ((u32)(x)|0xA0000000) /* physical to kseg1 */
|
||||
#define K1_TO_PHYS(x) ((u32)(x)&0x1FFFFFFF) /* kseg1 to physical */
|
||||
|
||||
#define IO_READ(addr) (*(volatile u32*)PHYS_TO_K1(addr))
|
||||
#define IO_WRITE(addr,data) (*(volatile u32*)PHYS_TO_K1(addr)=(u32)(data))
|
||||
|
||||
#define SAVE_SIZE_SRAM 32768
|
||||
#define SAVE_SIZE_SRAM128 131072
|
||||
#define SAVE_SIZE_EEP4k 4096
|
||||
#define SAVE_SIZE_EEP16k 16384
|
||||
#define SAVE_SIZE_FLASH 131072
|
||||
|
||||
#define ROM_ADDR 0xb0000000
|
||||
|
||||
|
||||
#define FRAM_EXECUTE_CMD 0xD2000000
|
||||
#define FRAM_STATUS_MODE_CMD 0xE1000000
|
||||
#define FRAM_ERASE_OFFSET_CMD 0x4B000000
|
||||
#define FRAM_WRITE_OFFSET_CMD 0xA5000000
|
||||
#define FRAM_ERASE_MODE_CMD 0x78000000
|
||||
#define FRAM_WRITE_MODE_CMD 0xB4000000
|
||||
#define FRAM_READ_MODE_CMD 0xF0000000
|
||||
|
||||
#define FRAM_STATUS_REG 0xA8000000
|
||||
#define FRAM_COMMAND_REG 0xA8010000
|
||||
|
||||
|
||||
#define CIC_6101 1
|
||||
#define CIC_6102 2
|
||||
#define CIC_6103 3
|
||||
#define CIC_6104 4
|
||||
#define CIC_6105 5
|
||||
#define CIC_6106 6
|
||||
|
||||
sprite_t *loadImage32DFS(char *fname);
|
||||
sprite_t *loadImageDFS(char *fname);
|
||||
sprite_t *loadImage32(u8 *tbuf, int size);
|
||||
void drawImage(display_context_t dcon, sprite_t *sprite);
|
||||
void _sync_bus(void);
|
||||
void _data_cache_invalidate_all(void);
|
||||
void printText(char *msg, int x, int y, display_context_t dcon);
|
||||
|
||||
// End ...
|
||||
int is_valid_rom(unsigned char *buffer);
|
||||
void swap_header(unsigned char* header, int loadlength);
|
||||
|
||||
void restoreTiming(void);
|
||||
|
||||
void simulate_boot(u32 boot_cic, u8 bios_cic);
|
||||
void globalTest(void);
|
||||
|
||||
|
||||
u8 getCicType(u8 bios_cic);
|
||||
int get_cic(unsigned char *buffer);
|
||||
int get_cic_save(char *cartid, int *cic, int *save);
|
||||
//const char* saveTypeToExtension(int type);
|
||||
const char* saveTypeToExtension(int type, int etype);
|
||||
int saveTypeToSize(int type);
|
||||
int getSaveFromCart(int stype, uint8_t *buffer);
|
||||
int pushSaveToCart(int stype, uint8_t *buffer);
|
||||
|
||||
int getSRAM( uint8_t *buffer,int size);
|
||||
int getSRAM32( uint8_t *buffer);
|
||||
int getSRAM128( uint8_t *buffer);
|
||||
int getEeprom4k( uint8_t *buffer);
|
||||
int getEeprom16k( uint8_t *buffer);
|
||||
int getFlashRAM( uint8_t *buffer);
|
||||
|
||||
int setSRAM(uint8_t *buffer,int size);
|
||||
int setSRAM32( uint8_t *buffer);
|
||||
int setSRAM128( uint8_t *buffer);
|
||||
int setEeprom4k( uint8_t *buffer);
|
||||
int setEeprom16k( uint8_t *buffer);
|
||||
int setFlashRAM( uint8_t *buffer);
|
Loading…
Reference in New Issue
Block a user