Initial Commit: v0.186

This commit is contained in:
Jay Oster 2014-06-28 22:10:11 -07:00
commit bb1e653309
44 changed files with 20582 additions and 0 deletions

15
.gitignore vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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 */

1931
fat.c Normal file

File diff suppressed because it is too large Load Diff

128
fat.h Normal file
View 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

Binary file not shown.

BIN
filesystem/done.wav Normal file

Binary file not shown.

BIN
filesystem/ed64_mono.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
filesystem/warning.wav Normal file

Binary file not shown.

275
font_patch/font.h Normal file
View 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
View File

@ -0,0 +1 @@
libdragon: include/font.h

BIN
header.ed64 Normal file

Binary file not shown.

301
ini.c Normal file
View 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
View 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
View 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
View 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 */

5784
menu.c Normal file

File diff suppressed because it is too large Load Diff

108
menu.h Normal file
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

1807
stb_truetype.h Normal file

File diff suppressed because it is too large Load Diff

43
strlib.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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 */

1640
utils.c Normal file

File diff suppressed because it is too large Load Diff

170
utils.h Normal file
View 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);