This commit is contained in:
Robin Jones 2017-10-26 18:49:34 +00:00 committed by GitHub
commit 58b9b33a64
88 changed files with 39998 additions and 14280 deletions

4
.gitignore vendored
View File

@ -13,3 +13,7 @@
## Temporary files
*.tmp
*~
*.VC.db*
*properties.json
/.vs
/.vscode

View File

@ -1,32 +0,0 @@
; 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

View File

@ -1,38 +1,61 @@
#
# Copyright (c) 2017 The Altra64 project contributors
# See LICENSE file in the project root for full license information.
#
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
HEADERNAME = header.ed64
HEADERTITLE = "EverDrive OS"
SRCDIR = ./src
INCDIR = ./inc
RESDIR = ./res
OBJDIR = ./obj
BINDIR = ./bin
TOOLSDIR = ./tools
LINK_FLAGS = -O1 -L$(ROOTDIR)/lib -L$(ROOTDIR)/mips64-elf/lib -ldragon -lmikmod -lmad -lyaml -lc -lm -ldragonsys -lnosys $(LIBS) -Tn64ld.x
PROG_NAME = menu
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -O1 -I$(ROOTDIR)/include -I$(ROOTDIR)/mips64-elf/include -lpthread -lrt -D_REENTRANT -DUSE_TRUETYPE
PROG_NAME = OS64
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -O1 -I$(INCDIR) -I$(ROOTDIR)/include -I$(ROOTDIR)/mips64-elf/include -lpthread -lrt -D_REENTRANT -DUSE_TRUETYPE $(SET_DEBUG)
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
SOURCES := $(wildcard $(SRCDIR)/*.c)
OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(PROG_NAME).v64: $(PROG_NAME).elf test.dfs
$(OBJCOPY) $(PROG_NAME).elf $(PROG_NAME).bin -O binary
rm -f OS64.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).v64: $ $(PROG_NAME).elf $(PROG_NAME).dfs
$(OBJCOPY) $(BINDIR)/$(PROG_NAME).elf $(BINDIR)/$(PROG_NAME).bin -O binary
rm -f $(BINDIR)/$(PROG_NAME).v64
$(N64TOOL) -l 4M -t $(HEADERTITLE) -h $(RESDIR)/$(HEADERNAME) -o $(BINDIR)/$(PROG_NAME).v64 $(BINDIR)/$(PROG_NAME).bin -s 1M $(BINDIR)/$(PROG_NAME).dfs
$(CHKSUM64PATH) $(BINDIR)/$(PROG_NAME).v64
$(PROG_NAME).elf : $(OBJS)
$(LD) -o $(PROG_NAME).elf $(OBJS) $(LINK_FLAGS)
$(PROG_NAME).elf : $(OBJECTS)
@mkdir -p $(BINDIR)
$(LD) -o $(BINDIR)/$(PROG_NAME).elf $(OBJECTS) $(LINK_FLAGS)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@mkdir -p $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
copy: $(PROG_NAME).v64
sh upload.sh
sh $(TOOLSDIR)/upload.sh
test.dfs:
$(MKDFSPATH) test.dfs ./filesystem/
$(PROG_NAME).dfs:
$(MKDFSPATH) $(BINDIR)/$(PROG_NAME).dfs $(RESDIR)/filesystem/
all: $(PROG_NAME).v64
debug: $(PROG_NAME).v64
debug: SET_DEBUG=-DDEBUG
clean:
rm -f *.v64 *.elf *.o *.bin *.dfs
rm -f $(BINDIR)/*.v64 $(BINDIR)/*.elf $(OBJDIR)/*.o $(BINDIR)/*.bin $(BINDIR)/*.dfs

168
README.md
View File

@ -1,37 +1,20 @@
# alt64
# Altra64
Alternative Everdrive64 menu
Kuroneko!
:\ /; _
; \___/ ; ; ;
,:-"' `"-:. / ;
_ /,---. ,---.\ _ _; /
_:>(( | ) ( | ))<:_ ,-""_,"
\````` `````/""""",-""
'-.._ v _..-' )
/ ___ ____,.. \
/ / | | | ( \. \
ctr / / | | | | \ \
`" `" `" `"
nyannyannyannyannyannyannyannyannyannyannyannyannyannyannyannyannyan
`alt64` is an open source menu for [Everdrive64](http://krikzz.com/). It was
`Altra64` is an open source menu for [Everdrive64](http://krikzz.com/) and is based on a fork of alt64 which was
originally written by saturnu, and released on the
[Everdrive64 forum](http://krikzz.com/forum/index.php?topic=816.0).
## Building
If you want to build the menu, you need an n64 toolchain. We'll use the
toolchain recommended by libdragon, with some updated versions.
If you want to build the menu, you need an n64 toolchain. When using windows 10 or Ubuntu, installation is totally automated through a script.
### Dependencies
* [libdragon](https://github.com/parasyte/libdragon)
* [libmikmod-n64](https://github.com/parasyte/libmikmod-n64)
### Dependencies (installed automatically)
* Windows 10 (Aniversary Update or above) / Ubuntu 16.04 (or above)
* [libdragon](https://github.com/DragonMinded/libdragon)
* [libmikmod (with n64 driver)](https://github.com/networkfusion/libmikmod)
* [libmad-n64](https://github.com/parasyte/libmad-n64)
* [libyaml](http://pyyaml.org/wiki/LibYAML)
@ -39,101 +22,56 @@ toolchain recommended by libdragon, with some updated versions.
*You may skip this step if it's already installed.*
Clone the `libdragon` repo and create a directory for the build.
Clone this `Altra64` repo to a directory of your choice.
```bash
$ git clone https://github.com/parasyte/libdragon.git
$ mkdir libdragon/build_gcc
$ cp libdragon/tools/build libdragon/build_gcc
$ cd libdragon/build_gcc
On Windows 10:
* Ensure that ["Windows Subsystem For Linux (Ubuntu)"](https://msdn.microsoft.com/en-gb/commandline/wsl/install_guide) is installed.
* browse to the tools directory and double click on ```setup-wsfl.cmd```.
On Ubuntu, browse to the tools directory and run the command ```$ chmod +x ./setup-linux.sh;source ./setup-linux.sh```
### Build `Altra64`
To build the Rom
from the projects root directory,
On Windows 10 run
```
Modify the `build` script to set your installation path. Here is the default:
```bash
# EDIT THIS LINE TO CHANGE YOUR INSTALL PATH!
export INSTALL_PATH=/usr/local/mips64-elf
> build
```
Build it! This can take an hour or more.
```bash
$ ./build
on linux
```
### Configure your Environment
Add the following environment variable to your `~/.bash_profile` or `~/.bashrc`
Be sure to use the same path that you configured in the build script!
```bash
export N64_INST=/usr/local/mips64-elf
```
### Build `libdragon`
Make sure you are in the `libdragon` top-level directory, and make sure `libpng`
is installed:
```bash
$ make && make install
$ make tools && make tools-install
```
### Build `libmikmod`
Clone `libmikmod-n64` and build:
```bash
$ git clone https://github.com/parasyte/libmikmod-n64.git
$ cd libmikmod-n64
$ make
$ make install
```
### Build `libmad-n64`
Clone `libmad-n64` and build, be sure to set the path according to your
toolchain installation path:
```bash
$ git clone https://github.com/parasyte/libmad-n64.git
$ cd libmad-n64
$ export PATH=$PATH:$(N64_INST)/bin
$ CFLAGS="-march=vr4300 -mtune=vr4300 -mno-extern-sdata" \
LDFLAGS="-L$(N64_INST)/lib" LIBS="-lc -lnosys" \
./configure --host=mips64-elf --disable-shared \
--prefix=$(N64_INST) --enable-speed --enable-fpm=mips
$ make
$ make install
```
### Build `libyaml`
Download libyaml 0.1.6 and build, be sure to set the path according to your
toolchain installation path:
```bash
$ hg clone https://bitbucket.org/xi/libyaml
$ cd libyaml
$ hg update 0.1.6
$ ./bootstrap
$ export PATH=$PATH:$(N64_INST)/bin
$ CFLAGS="-std=gnu99 -march=vr4300 -mtune=vr4300" \
LDFLAGS="-L$(N64_INST)/lib -Tn64ld.x" \
LIBS="-ldragon -lc -ldragonsys -lnosys" \
./configure --host=mips64-elf --prefix=$(N64_INST)
$ make
$ make install
```
### Build `alt64`
Finally, we can clone `alt64` and build it!
```bash
$ git clone https://github.com/parasyte/alt64.git
$ make
```
If it all worked, you will find `OS64.v64` in the `Altra64` bin directory.
If it all worked, you will find `OS64.v64` in the `alt64` top-level directory.
### Debug Build `Altra64`
To build the debug version of the Rom
from the projects root directory,
On Windows 10 run
```
> build debug
```
on linux
```
$ make debug
```
If it all worked, you will find `OS64.v64` in the `Altra64` bin directory.
### Clean `Altra64`
Finally, we can clean the build objects from the project
from the projects root directory,
On Windows 10 run
```
> build clean
```
on linux
```
$ make clean
```
Enjoy!

23
build.cmd Normal file
View File

@ -0,0 +1,23 @@
::
:: Copyright (c) 2017 The Altra64 project contributors
:: See LICENSE file in the project root for full license information.
::
@echo off
set "SystemPath=%SystemRoot%\\System32"
IF EXIST %WINDIR%\\sysnative\\reg.exe (
set "SystemPath=%SystemRoot%\Sysnative"
echo. "32-bit process..."
)
set env="/usr/local/libdragon"
IF %1.==. (
echo. "no parameter"
%SystemPath%\\bash --verbose -c "export N64_INST=%env%; make"
) ELSE (
echo. "parameter: %1"
%SystemPath%\\bash --verbose -c "export N64_INST=%env%; make %1"
)
:pause

29
disk.h
View File

@ -1,29 +0,0 @@
/*
* 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 */

1931
fat.c

File diff suppressed because it is too large Load Diff

128
fat.h
View File

@ -1,128 +0,0 @@
/*
* 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 */

11
inc/chksum64.h Normal file
View File

@ -0,0 +1,11 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _CHKSUM64_H
#define _CHKSUM64_H
void checksum_sdram(void);
#endif

12
inc/cic.h Normal file
View File

@ -0,0 +1,12 @@
#define CIC_6101 1
#define CIC_6102 2
#define CIC_6103 3
#define CIC_5101 4 //aleck64
//#define CIC_6104 6104 //Unused in any game so used for Aleck64 instead
#define CIC_6105 5
#define CIC_6106 6
#define CIC_5167 7 //64dd conv
int get_cic(unsigned char *rom_data);

19
inc/debug.h Normal file
View File

@ -0,0 +1,19 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _DEBUG_H
#define _DEBUG_H
#ifdef DEBUG
#define TRACEF(disp, text, ...) dbg_printf(disp, text, __VA_ARGS__);
#define TRACE(disp, text) printText(text, 3, -1, disp);
#else
#define TRACEF(disp, text, ...) do { if (0) dbg_printf(disp, text, __VA_ARGS__); sleep(5000); } while (0)
#define TRACE(disp, text) do { if (0) printText(text, 3, -1, disp); } didplay_show(disp); sleep(5000); while (0)
#endif
void dbg_printf(display_context_t disp, const char *fmt, ...);
#endif

80
inc/diskio.h Normal file
View File

@ -0,0 +1,80 @@
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,9 +1,8 @@
/*
* File: errors.h
* Author: KRIK
*
* Created on 14 Ìàé 2011 ã., 7:17
*/
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#ifndef _ERRORS_H
#define _ERRORS_H
@ -66,5 +65,5 @@
#define SD_INIT_ERROR 80
#endif /* _ERRORS_H */
#endif /* _ERRORS_H */

View File

@ -1,9 +1,8 @@
/*
* File: everdrive.h
* Author: KRIK
*
* Created on 22 Àïðåëü 2011 ã., 20:46
*/
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#ifndef _EVERDRIVE_H
#define _EVERDRIVE_H
@ -76,6 +75,7 @@ u8 evd_SPI(u8 dat);
void evd_mmcSetDmaSwap(u8 state);
u8 evd_mmcReadToCart(u32 cart_addr, u32 len);
void evd_ulockRegs(void);
void evd_lockRegs();
u16 evd_readReg(u8 reg);
void evd_writeReg(u8 reg, u16 val);
@ -121,5 +121,6 @@ u8 evd_mmcOpenRead(u32 addr);
u8 evd_mmcReadNextBlock(void *dat);
void evd_mmcCloseRW();
*/
#endif /* _EVERDRIVE_H */
#endif /* _EVERDRIVE_H */

364
inc/ff.h Normal file
View File

@ -0,0 +1,364 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.13 /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/
/----------------------------------------------------------------------------*/
#ifndef FF_DEFINED
#define FF_DEFINED 87030 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if FF_DEFINED != FFCONF_DEF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if FF_MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#endif
/* Type of path name strings on FatFs API */
#if FF_LFN_UNICODE && FF_USE_LFN /* Unicode (UTF-16) string */
#ifndef _INC_TCHAR
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#define _INC_TCHAR
#endif
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#define _INC_TCHAR
#endif
#endif
/* Type of file size variables */
#if FF_FS_EXFAT
#if !FF_USE_LFN
#error LFN must be enabled when enable exFAT
#endif
typedef QWORD FSIZE_t;
#else
typedef DWORD FSIZE_t;
#endif
/* Filesystem object structure (FATFS) */
typedef struct {
BYTE fs_type; /* Filesystem type (0:N/A) */
BYTE pdrv; /* Physical drive number */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* Volume mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
#if FF_MAX_SS != FF_MIN_SS
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
#endif
#if FF_USE_LFN
WCHAR* lfnbuf; /* LFN working buffer */
#endif
#if FF_FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
#endif
#if FF_FS_REENTRANT
FF_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
#endif
#if FF_FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
#if FF_FS_EXFAT
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD volbase; /* Volume base sector */
DWORD fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* Object ID and allocation information (FFOBJID) */
typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if FF_FS_EXFAT
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
#endif
#if FF_FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} FFOBJID;
/* File object structure (FIL) */
typedef struct {
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !FF_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
#endif
#if FF_USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !FF_FS_TINY
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if FF_USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[13]; /* Altenative file name */
TCHAR fname[FF_MAX_LFN + 1]; /* Primary file name */
#else
TCHAR fname[13]; /* File name */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
FRESULT f_setcp (WORD cp); /* Set current code page */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#define f_unmount(path) f_mount(0, path, 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !FF_FS_READONLY && !FF_FS_NORTC
DWORD get_fattime (void);
#endif
/* LFN support functions */
#if FF_USE_LFN /* Code conversion (defined in unicode.c) */
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem (WCHAR uni, WORD cp); /* Unicode to OEM code conversion */
WCHAR ff_wtoupper (WCHAR uni); /* Unicode upper-case conversion */
#endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
/* Sync functions */
#if FF_FS_REENTRANT
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01
#define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA_OPEN_APPEND 0x30
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#ifdef __cplusplus
}
#endif
#endif /* FF_DEFINED */

269
inc/ffconf.h Normal file
View File

@ -0,0 +1,269 @@
/*---------------------------------------------------------------------------/
/ FatFs - Configuration file
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 87030 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define FF_FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define FF_USE_STRFUNC 1
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define FF_USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_USE_FASTSEEK 0
/* This option switches fast seek function. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
#define FF_USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define FF_USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define FF_CODE_PAGE 437
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect code page setting can cause a file open failure.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
/ 0 - Include all code pages above and configured by f_setcp()
*/
#define FF_USE_LFN 1
#define FF_MAX_LFN 255
/* The FF_USE_LFN switches the support for LFN (long file name).
/
/ 0: Disable LFN. FF_MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ to the project. The working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional 608 bytes at exFAT enabled. FF_MAX_LFN can be in range from 12 to 255.
/ It should be set 255 to support full featured LFN operations.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define FF_LFN_UNICODE 0
/* This option switches character encoding on the API, 0:ANSI/OEM or 1:UTF-16,
/ when LFN is enabled. Also behavior of string I/O functions will be affected by
/ this option. When LFN is not enabled, this option has no effect.
*/
#define FF_STRF_ENCODE 3
/* When FF_LFN_UNICODE = 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions.
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
*/
#define FF_FS_RPATH 0
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* FF_STR_VOLUME_ID switches string support for volume ID.
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define FF_MULTI_PARTITION 0
/* This option switches support for multiple volumes on the physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define FF_MIN_SS 512
#define FF_MAX_SS 512
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/ for variable sector size mode and disk_ioctl() function needs to implement
/ GET_SECTOR_SIZE command. */
#define FF_USE_TRIM 0
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
#define FF_FS_EXFAT 1
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled.
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 1
#define FF_NORTC_MON 10
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2017
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
#define FF_FS_LOCK 0
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* #include <windows.h> // O/S definitions */
/*--- End of configuration options ---*/

View File

@ -1,3 +1,8 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
/**
* @file font.h

31
inc/hashtable.h Normal file
View File

@ -0,0 +1,31 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 @marekweb https://github.com/marekweb/datastructs-c
// See LICENSE file in the project root for full license information.
//
#ifndef _HASHTABLE_H
#define _HASHTABLE_H
typedef struct hashtable hashtable;
void hashtable_destroy(hashtable *t);
typedef struct hashtable_entry hashtable_entry;
hashtable_entry *hashtable_body_allocate(unsigned int capacity);
hashtable *hashtable_create();
void hashtable_remove(hashtable *t,char *key);
void hashtable_resize(hashtable *t,unsigned int capacity);
void hashtable_set(hashtable *t,char *key,void *value);
void *hashtable_get(hashtable *t,char *key);
unsigned int hashtable_find_slot(hashtable *t,char *key);
unsigned long hashtable_hash(char *str);
struct hashtable {
unsigned int size;
unsigned int capacity;
hashtable_entry* body;
};
struct hashtable_entry {
char* key;
void* value;
};
#endif

14
inc/image.h Normal file
View File

@ -0,0 +1,14 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _IMAGE_H
#define _IMAGE_H
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);
#endif

View File

38
inc/integer.h Normal file
View File

@ -0,0 +1,38 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef FF_INTEGER
#define FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
#endif
#endif

41
inc/main.h Normal file
View File

@ -0,0 +1,41 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#ifndef MAIN_H
#define MAIN_H
//TODO: these should probably be static not protos in main
void bootRom(display_context_t disp, int silent);
void loadrom(display_context_t disp, u8 *buff, int fast);
void readSDcard(display_context_t disp, char *directory);
int saveTypeToSd(display_context_t disp, char* save_filename ,int type);
void drawShortInfoBox(display_context_t disp, char* text, u8 mode);
void drawTextInput(display_context_t disp,char *msg);
//#define ishexchar(c) (((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f')))
/**
* @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))
#endif

View File

@ -1,13 +1,11 @@
/*
* File: mem.h
* Author: krik
*
* Created on 2 Èþíü 2011 ã., 4:07
*/
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#ifndef _MEM_H
#define _MEM_H
#include "types.h"
#define SPI_SPEED_INIT 2
#define SPI_SPEED_25 1
@ -28,7 +26,7 @@ void memSpiSetSpeed(u8 speed);
void spiReadBlock(void *dat);
void spiWriteBlock(void *dat);
u8 memSpiRead(void *dst, u16 slen);
u8 memSpiWrite(void *src);
u8 memSpiWrite(const void *src);
//u8 mem_spi(u8 dat);
void memfill(void *dst, u8 val, u16 len);
void memcopy(void *src, void *dst, u16 len);

17
inc/memorypak.h Normal file
View File

@ -0,0 +1,17 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _MEMORYPAK_H
#define _MEMORYPAK_H
//TODO: not sure if this is correct!!!
extern char *mempak_path;
int file_to_mpk(display_context_t disp, u8 *filename);
void mpk_to_file(display_context_t disp, char *mpk_filename, int quick);
void view_mpk_file(display_context_t disp, char *mpk_filename);
void view_mpk(display_context_t disp);
#endif

15
inc/menu.h Normal file
View File

@ -0,0 +1,15 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _MENU_H_
#define _MENU_H_
extern int text_offset;
void printText(char *msg, int x, int y, display_context_t dcon);
void menu_about(display_context_t disp);
#endif

14
inc/mp3.h Normal file
View File

@ -0,0 +1,14 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#ifndef _MP3_H_
#define _MP3_H_
void mp3_Start(char *fname, long long *samples, int *rate, int *channels);
void mp3_Stop(void);
int mp3_Update(char *buf, int bytes);
#endif // _MP3_H_

View File

@ -1,11 +1,14 @@
// rom.h
// rom tools - header inspect
#include <stdint.h>
#include <libdragon.h>
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#ifndef _ROM_H
#define _ROM_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)
@ -146,65 +149,13 @@
#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
#if !defined(MIN)
#define MIN(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; \
})
#endif
//void romFill(...);
void pif_boot();
#if !defined(MAX)
#define MAX(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; \
})
#endif
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, u32 *cheat_list[2]);
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);
#endif

27
inc/sd.h Normal file
View File

@ -0,0 +1,27 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#ifndef _SD_H
#define _SD_H
#include "types.h"
u8 sdGetInterface();
u8 sdInit();
u8 sdRead(u32 sector, u8 *buff, u16 count);
u8 sdWrite(u32 sector, const u8 *buff, u16 count);
void sdSetInterface(u32 interface);
#define WAIT 1024
#define DISK_IFACE_SPI 0
#define DISK_IFACE_SD 1
#endif /* _DISK_H */

14
inc/sound.h Normal file
View File

@ -0,0 +1,14 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _SOUND_H
#define _SOUND_H
void sndInit(void);
void sndPlayBGM(char* filename);
void sndStopAll(void);
void sndPlaySFX(char* filename);
void sndUpdate(void);
#endif

View File

@ -1,10 +1,16 @@
//sram.h
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#ifndef _SRAM_H
#define _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);
@ -30,3 +36,5 @@ 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);
#endif

6755
inc/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

3267
inc/stb_truetype.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,14 @@
#ifndef STRLIB_H_
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#ifndef _STRLIB_H
#define _STRLIB_H
#include "types.h"
enum strtrim_mode_t {
STRLIB_MODE_ALL = 0,
STRLIB_MODE_RIGHT = 0x01,
@ -21,4 +31,15 @@ char *triml(char *s);
char *trimr(char *s);
char *trim(char *s);
char *strlibkill(char *s);
void strhicase(u8 *str, u8 len);
u16 strcon(u8 *str1, u8 *str2, u8 *dst, u16 max_len);
u8 slen(u8 *str);
u8 scopy(u8 *src, u8 *dst);
u8 streq(u8 *str1, u8 *str2);
u8 streql(u8 *str1, u8 *str2, u8 len);
u16 strContain(u8 *target, u8 *str);
#endif

View File

@ -1,15 +1,13 @@
/*
* File: tools.h
* Author: KRIK
*
* Created on 16 Àïðåëü 2011 ã., 2:30
*/
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#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);
@ -20,13 +18,7 @@ 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;
@ -57,5 +49,5 @@ typedef struct {
extern Options_st options;
extern u32 asm_date;
#endif /* _TOOLS_H */
#endif /* _SYS_H */

View File

@ -1,15 +1,14 @@
/*
* File: types.h
* Author: KRIK
*
* Created on 16 Àïðåëü 2011 ã., 2:24
*/
#include <stdint.h>
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#ifndef _TYPES_H
#define _TYPES_H
#include <stdint.h>
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned long
@ -33,4 +32,3 @@ typedef uint64_t sim_u64;
#endif /* _TYPES_H */

14
inc/usb.h Normal file
View File

@ -0,0 +1,14 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 KRIK
// See LICENSE file in the project root for full license information.
//
#ifndef _USB_H
#define _USB_H
//#include "types.h"
u8 usbListener();
#endif /* _USB_H */

70
inc/utils.h Normal file
View File

@ -0,0 +1,70 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#ifndef _UTILS_H
#define _UTILS_H
// rom.h
// rom tools - header inspect
//#include <stdint.h>
//#include <libdragon.h>
//#include "rom.h"
#if !defined(MIN)
#define MIN(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; \
})
#endif
#if !defined(MAX)
#define MAX(a, b) ({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; \
})
#endif
void _sync_bus(void);
void _data_cache_invalidate_all(void);
// End ...
void restoreTiming(void);
void simulate_boot(u32 boot_cic, u8 bios_cic, u32 *cheat_list[2]);
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);
#endif

11
inc/version.h Normal file
View File

@ -0,0 +1,11 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#ifndef _VERSION_H
#define _VERSION_H
const char* Altra64_GetVersionString(void);
#endif

4453
menu.c

File diff suppressed because it is too large Load Diff

89
menu.h
View File

@ -1,89 +0,0 @@
//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, u32 *cheat_lists[2]);
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))

9
mp3.h
View File

@ -1,9 +0,0 @@
#ifndef _MP3_H_
#define _MP3_H_
void start_mp3(char *fname, long long *samples, int *rate, int *channels);
void stop_mp3(void);
int update_mp3(char *buf, int bytes);
#endif // _MP3_H_

32
res/ALT64.INI Normal file
View File

@ -0,0 +1,32 @@
; alt64 config file
[ed64] ; Menu config
build=18 ; Release build number
border_color_1=FFFFFFFF ; 0x00000080 RGBT
border_color_2=3F3F3FFF ; 0x3F3F3FFF RGBT 00000060 w light
box_color=000000B6 ; 0x00000080 RGBT
selection_color=80008070 ; 0x80008070 RGBT 6495ED60
list_font_color=CDC9C940 ; 0x80008070 RGBT 6495ED60
list_dir_font_color=FFFFE040 ; 0x80008070 RGBT 6495ED60
selection_font_color=FFB90FFF ; 0x80008070 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=2 ; 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=1 ; 1=hide 0=don't hide
mempak_path=/MEMPAKS/ ; surround with slashes
save_path=SDSAVE ; save directory inside ED64
[user]
name = Altra64 ; Username
[gblite]
save_path=/ED64/SDSAVE/ ; save directory surround with slashes
tv_mode=0 ; 1=ntsc 2=pal 3=mpal 0=force_off

Binary file not shown.

View File

@ -18,11 +18,11 @@
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>
#include "sys.h"
#include "chksum64.h"
#define BUFSIZE 0x8000

117
src/cic.c Normal file
View File

@ -0,0 +1,117 @@
//
// si/cic.c: PIF CIC security/lock out algorithms.
//
// CEN64: Cycle-Accurate Nintendo 64 Emulator.
// Copyright (C) 2015, Tyler J. Stachecki.
//
// This file is subject to the terms and conditions defined in
// 'LICENSE', which is part of this source code package.
//
//#include "common.h"
//#include "si/cic.h"
#include <stdint.h>
#include <stddef.h>
#include "cic.h"
// CIC seeds and status bits passed from PIF to IPL through PIF RAM
// Bits | Description
// 00080000 | ROM type (0 = Game Pack, 1 = DD)
// 00040000 | Version
// 00020000 | Reset Type (0 = cold reset, 1 = NMI)
// 0000FF00 | CIC IPL3 seed value
// 000000FF | CIC IPL2 seed value
// #define CIC_SEED_NUS_5101 0x0000AC00U
// #define CIC_SEED_NUS_6101 0x00043F3FU
// #define CIC_SEED_NUS_6102 0x00003F3FU
// #define CIC_SEED_NUS_6103 0x0000783FU
// #define CIC_SEED_NUS_6105 0x0000913FU
// #define CIC_SEED_NUS_6106 0x0000853FU
// #define CIC_SEED_NUS_8303 0x0000DD00U
#define CRC_NUS_5101 0x587BD543U
#define CRC_NUS_6101 0x6170A4A1U
#define CRC_NUS_7102 0x009E9EA3U
#define CRC_NUS_6102 0x90BB6CB5U
#define CRC_NUS_6103 0x0B050EE0U
#define CRC_NUS_6105 0x98BC2C86U
#define CRC_NUS_6106 0xACC8580AU
#define CRC_NUS_8303 0x0E018159U
static uint32_t si_crc32(const uint8_t *data, size_t size);
// Determines the CIC seed for a cart, given the ROM data.
//int get_cic_seed(const uint8_t *rom_data, uint32_t *cic_seed) {
int get_cic(unsigned char *rom_data) {
uint32_t crc = si_crc32(rom_data + 0x40, 0x1000 - 0x40);
uint32_t aleck64crc = si_crc32(rom_data + 0x40, 0xC00 - 0x40);
if (aleck64crc == CRC_NUS_5101)
return 4;//*cic_seed = CIC_SEED_NUS_5101;
else
{
switch (crc) {
case CRC_NUS_6101:
case CRC_NUS_7102:
//*cic_seed = CIC_SEED_NUS_6101;
return 1;
break;
case CRC_NUS_6102:
//*cic_seed = CIC_SEED_NUS_6102;
return 2;
break;
case CRC_NUS_6103:
//*cic_seed = CIC_SEED_NUS_6103;
return 3;
break;
case CRC_NUS_6105:
//*cic_seed = CIC_SEED_NUS_6105;
return 5;
break;
case CRC_NUS_6106:
//*cic_seed = CIC_SEED_NUS_6106;
return 6;
break;
//case CRC_NUS_8303: //not sure if this is necessary as we are using cart conversions
//*cic_seed = CIC_SEED_NUS_8303;
//return 7;
//break;
default:
break;
}
}
return 2;
}
uint32_t si_crc32(const uint8_t *data, size_t size) {
uint32_t table[256];
unsigned n, k;
uint32_t c;
for (n = 0; n < 256; n++) {
c = (uint32_t) n;
for (k = 0; k < 8; k++) {
if (c & 1)
c = 0xEDB88320L ^ (c >> 1);
else
c = c >> 1;
}
table[n] = c;
}
c = 0L ^ 0xFFFFFFFF;
for (n = 0; n < size; n++)
c = table[(c ^ data[n]) & 0xFF] ^ (c >> 8);
return c ^ 0xFFFFFFFF;
}

24
src/debug.c Normal file
View File

@ -0,0 +1,24 @@
#include <stdarg.h>
#include <stdio.h>
#include <libdragon.h>
#include "types.h"
#include "debug.h"
#include "menu.h"
#include "sys.h"
void dbg_printf(display_context_t disp, const char *fmt, ...)
{
char buf[256] = {0};
setbuf(stderr, buf);
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
u8 tmp[256] = {0};
sprintf(tmp, "%s", buf);
printText(tmp, 3, -1, disp);
display_show(disp);
sleep(5000);
}

300
src/diskio.c Normal file
View File

@ -0,0 +1,300 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
#include "sd.h"
/* Definitions of physical drive number for each drive */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
// int result;
// switch (pdrv) {
// case DEV_RAM :
// result = RAM_disk_status();
// // translate the reslut code here
// return stat;
// case DEV_MMC :
// result = MMC_disk_status();
// // translate the reslut code here
// return stat;
// case DEV_USB :
// result = USB_disk_status();
// // translate the reslut code here
// return stat;
// }
// return STA_NOINIT;
if(pdrv)
{
return STA_NOINIT;
}
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Initialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
// switch (pdrv) {
// case DEV_RAM :
// result = RAM_disk_initialize();
// // translate the reslut code here
// return stat;
// case DEV_MMC :
// result = MMC_disk_initialize();
// // translate the reslut code here
// return stat;
// case DEV_USB :
// result = USB_disk_initialize();
// // translate the reslut code here
// return stat;
// }
stat=sdInit(); //SD card initialization
if(stat == STA_NODISK)
{
return STA_NODISK;
}
else if(stat != 0)
{
return STA_NOINIT;
}
else
{
return 0;
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
// int result;
// switch (pdrv) {
// case DEV_RAM :
// // translate the arguments here
// result = RAM_disk_read(buff, sector, count);
// // translate the reslut code here
// return res;
// case DEV_MMC :
// // translate the arguments here
// result = MMC_disk_read(buff, sector, count);
// // translate the reslut code here
// return res;
// case DEV_USB :
// // translate the arguments here
// result = USB_disk_read(buff, sector, count);
// // translate the reslut code here
// return res;
// }
// return RES_PARERR;
if (pdrv || !count)
{
return RES_PARERR;
}
res = sdRead(sector, buff, count);
if(res == 0x00)
{
return RES_OK;
}
else
{
return RES_ERROR;
}
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
// int result;
// switch (pdrv) {
// case DEV_RAM :
// // translate the arguments here
// result = RAM_disk_write(buff, sector, count);
// // translate the reslut code here
// return res;
// case DEV_MMC :
// // translate the arguments here
// result = MMC_disk_write(buff, sector, count);
// // translate the reslut code here
// return res;
// case DEV_USB :
// // translate the arguments here
// result = USB_disk_write(buff, sector, count);
// // translate the reslut code here
// return res;
// }
//return RES_PARERR;
if (pdrv || !count)
{
return RES_PARERR;
}
res = sdWrite(sector, buff, count);
if(res == 0)
{
return RES_OK;
}
else
{
return RES_ERROR;
}
}
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
// int result;
// switch (pdrv) {
// case DEV_RAM :
// // Process of the command for the RAM drive
// return res;
// case DEV_MMC :
// // Process of the command for the MMC/SD card
// return res;
// case DEV_USB :
// // Process of the command the USB drive
// return res;
// }
switch (cmd) {
case CTRL_SYNC:
return RES_OK;
case GET_SECTOR_SIZE:
*(WORD*)buff = 512;
return RES_OK;
case GET_SECTOR_COUNT:
//*(DWORD*)buff = sdGetSectors();
return RES_OK;
case GET_BLOCK_SIZE:
//*(DWORD*)buff = sdGetBlockSize();
return RES_OK;
}
return RES_PARERR;
}
DWORD get_fattime (void)
{
//TODO: can we use the V3 RTC?
return 0;
}

View File

@ -1,12 +1,12 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#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

6204
src/ff.c Normal file

File diff suppressed because it is too large Load Diff

171
src/ffsystem.c Normal file
View File

@ -0,0 +1,171 @@
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */
/* (C)ChaN, 2017 */
/*------------------------------------------------------------------------*/
#include "ff.h"
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free */
)
{
free(mblock); /* Free the memory block with POSIX API */
}
#endif
#if FF_FS_REENTRANT /* Mutal exclusion */
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object for the volume, such as semaphore and mutex.
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
*/
//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
FF_SYNC_t *sobj /* Pointer to return the created sync object */
)
{
/* Win32 */
*sobj = CreateMutex(NULL, FALSE, NULL);
return (int)(*sobj != INVALID_HANDLE_VALUE);
/* uITRON */
// T_CSEM csem = {TA_TPRI,1,1};
// *sobj = acre_sem(&csem);
// return (int)(*sobj > 0);
/* uC/OS-II */
// OS_ERR err;
// *sobj = OSMutexCreate(0, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// *sobj = xSemaphoreCreateMutex();
// return (int)(*sobj != NULL);
/* CMSIS-RTOS */
// *sobj = osMutexCreate(Mutex + vol);
// return (int)(*sobj != NULL);
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
/* Win32 */
return (int)CloseHandle(sobj);
/* uITRON */
// return (int)(del_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// vSemaphoreDelete(sobj);
// return 1;
/* CMSIS-RTOS */
// return (int)(osMutexDelete(sobj) == osOK);
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
FF_SYNC_t sobj /* Sync object to wait */
)
{
/* Win32 */
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
/* uITRON */
// return (int)(wai_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
/* CMSIS-RTOS */
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* Win32 */
ReleaseMutex(sobj);
/* uITRON */
// sig_sem(sobj);
/* uC/OS-II */
// OSMutexPost(sobj);
/* FreeRTOS */
// xSemaphoreGive(sobj);
/* CMSIS-RTOS */
// osMutexRelease(sobj);
}
#endif

15566
src/ffunicode.c Normal file

File diff suppressed because it is too large Load Diff

163
src/hashtable.c Normal file
View File

@ -0,0 +1,163 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2011 @marekweb https://github.com/marekweb/datastructs-c
// See LICENSE file in the project root for full license information.
//
/**
* Hashtable implementation
* Uses dynamic addressing with linear probing.
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "hashtable.h"
/*
* Interface section used for `makeheaders`.
*/
#if INTERFACE
struct hashtable_entry {
char* key;
void* value;
};
struct hashtable {
unsigned int size;
unsigned int capacity;
hashtable_entry* body;
};
#endif
#define HASHTABLE_INITIAL_CAPACITY 2
/**
* Compute the hash value for the given string.
* Implements the djb k=33 hash function.
*/
unsigned long hashtable_hash(char* str)
{
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
/**
* Find an available slot for the given key, using linear probing.
*/
unsigned int hashtable_find_slot(hashtable* t, char* key)
{
int index = hashtable_hash(key) % t->capacity;
while (t->body[index].key != NULL && strcmp(t->body[index].key, key) != 0) {
index = (index + 1) % t->capacity;
}
return index;
}
/**
* Return the item associated with the given key, or NULL if not found.
*/
void* hashtable_get(hashtable* t, char* key)
{
int index = hashtable_find_slot(t, key);
if (t->body[index].key != NULL) {
return t->body[index].value;
} else {
return NULL;
}
}
/**
* Assign a value to the given key in the table.
*/
void hashtable_set(hashtable* t, char* key, void* value)
{
int index = hashtable_find_slot(t, key);
if (t->body[index].key != NULL) {
/* Entry exists; update it. */
t->body[index].value = value;
} else {
t->size++;
/* Create a new entry */
if ((float)t->size / t->capacity > 0.8) {
/* Resize the hash table */
hashtable_resize(t, t->capacity * 2);
index = hashtable_find_slot(t, key);
}
t->body[index].key = key;
t->body[index].value = value;
}
}
/**
* Remove a key from the table
*/
void hashtable_remove(hashtable* t, char* key)
{
int index = hashtable_find_slot(t, key);
if (t->body[index].key != NULL) {
t->body[index].key = NULL;
t->body[index].value = NULL;
t->size--;
}
}
/**
* Create a new, empty hashtable
*/
hashtable* hashtable_create()
{
hashtable* new_ht = malloc(sizeof(hashtable));
new_ht->size = 0;
new_ht->capacity = HASHTABLE_INITIAL_CAPACITY;
new_ht->body = hashtable_body_allocate(new_ht->capacity);
return new_ht;
}
#if 0
/**
* Adds all items from another table.
*/
hashtable* hashtable_merge(hashtable* ht, hashtable* other)
{
}
#endif
/**
* Allocate a new memory block with the given capacity.
*/
hashtable_entry* hashtable_body_allocate(unsigned int capacity)
{
return (hashtable_entry*)calloc(capacity, sizeof(hashtable_entry));
}
/**
* Resize the allocated memory.
* Warning: clears the table of all entries.
*/
void hashtable_resize(hashtable* t, unsigned int capacity)
{
assert(capacity >= t->size);
unsigned int old_capacity = t->capacity;
hashtable_entry* old_body = t->body;
t->body = hashtable_body_allocate(capacity);
t->capacity = capacity;
for (int i = 0; i < old_capacity; i++) {
if (old_body[i].key != NULL) {
hashtable_set(t, old_body[i].key, old_body[i].value);
}
}
}
/**
* Destroy the table and deallocate it from memory. This does not deallocate the contained items.
*/
void hashtable_destroy(hashtable* t)
{
free(t->body);
free(t);
}

182
src/image.c Normal file
View File

@ -0,0 +1,182 @@
#include <libdragon.h>
#include "types.h"
#include "image.h"
//#define STBI_HEADER_FILE_ONLY
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
/*
* Load an image from the rom filesystem, returning a pointer to the
* sprite that hold the image.
*/
sprite_t *loadImageDFS(char *fname) {
int size, x, y, n, fd;
u8 *tbuf;
u8 *ibuf;
sprite_t *sbuf;
fd = dfs_open(fname);
if (fd < 0)
return 0; // couldn't open image
size = dfs_size(fd);
tbuf = malloc(size);
if (!tbuf) {
dfs_close(fd);
return 0; // out of memory
}
dfs_read(tbuf, 1, size, fd);
dfs_close(fd);
ibuf = stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
free(tbuf);
if (!ibuf)
return 0; // couldn't decode image
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 2);
if (!sbuf) {
stbi_image_free(ibuf);
return 0; // out of memory
}
sbuf->width = x;
sbuf->height = y;
sbuf->bitdepth = 2;
sbuf->format = 0;
sbuf->hslices = x / 32;
sbuf->vslices = y / 16;
color_t *src = (color_t*)ibuf;
u16 *dst = (u16*)((u32)sbuf + sizeof(sprite_t));
for (int j=0; j<y; j++)
for (int i=0; i<x; i++)
dst[i + j*x] = graphics_convert_color(src[i + j*x]) & 0x0000FFFF;
/* Invalidate data associated with sprite in cache */
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
stbi_image_free(ibuf);
return sbuf;
}
sprite_t *loadImage32(u8 *png, int size) {
int x, y, n, fd;
u8 *tbuf;
u32 *ibuf;
sprite_t *sbuf;
tbuf = malloc(size);
memcpy(tbuf,png,size);
ibuf = (u32*)stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
free(tbuf);
if (!ibuf)
return 0; // couldn't decode image
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 4);
if (!sbuf) {
stbi_image_free(ibuf);
return 0; // out of memory
}
sbuf->width = x;
sbuf->height = y;
sbuf->bitdepth = 4;
sbuf->format = 0;
sbuf->hslices = x / 32;
sbuf->vslices = y / 32;
// color_t *src = (color_t*)ibuf;
u32 *dst = (u32*)((u32)sbuf + sizeof(sprite_t));
for (int j=0; j<y; j++)
for (int i=0; i<x; i++)
dst[i + j*x] = ibuf[i + j*x];
/* Invalidate data associated with sprite in cache */
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
stbi_image_free(ibuf);
return sbuf;
}
sprite_t *loadImage32DFS(char *fname) {
int size, x, y, n, fd;
u8 *tbuf;
u32 *ibuf;
sprite_t *sbuf;
fd = dfs_open(fname);
if (fd < 0)
return 0; // couldn't open image
size = dfs_size(fd);
tbuf = malloc(size);
if (!tbuf) {
dfs_close(fd);
return 0; // out of memory
}
dfs_read(tbuf, 1, size, fd);
dfs_close(fd);
ibuf = (u32*)stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
free(tbuf);
if (!ibuf)
return 0; // couldn't decode image
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 4);
if (!sbuf) {
stbi_image_free(ibuf);
return 0; // out of memory
}
sbuf->width = x;
sbuf->height = y;
sbuf->bitdepth = 4;
sbuf->format = 0;
sbuf->hslices = x / 32;
sbuf->vslices = y / 32;
// color_t *src = (color_t*)ibuf;
u32 *dst = (u32*)((u32)sbuf + sizeof(sprite_t));
for (int j=0; j<y; j++)
for (int i=0; i<x; i++)
dst[i + j*x] = ibuf[i + j*x];
/* Invalidate data associated with sprite in cache */
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
stbi_image_free(ibuf);
return sbuf;
}
/*
* Draw an image to the screen using the sprite passed.
*/
void drawImage(display_context_t dcon, sprite_t *sprite) {
int x, y = 0;
rdp_sync(SYNC_PIPE);
rdp_set_default_clipping();
rdp_enable_texture_copy();
rdp_attach_display(dcon);
// Draw image
for (int j=0; j<sprite->vslices; j++) {
x = 0;
for (int i=0; i<sprite->hslices; i++) {
rdp_sync(SYNC_PIPE);
rdp_load_texture_stride(0, 0, MIRROR_DISABLED, sprite, j*sprite->hslices + i);
rdp_draw_sprite(0, x, y);
x += 32;
}
y += 16;
}
rdp_detach_display();
}

View File

4575
src/main.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,16 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include "types.h"
#include "everdrive.h"
#include "sys.h"
u8 spi_dma;
#include "errors.h"
#include "mem.h"
u8 spi_dma;
u8 memSpiReadDma(void *dst, u16 slen);
u8 memSpiReadPio(void *dst, u16 slen);
u8 mem_buff[512];
@ -106,7 +110,7 @@ u8 memSpiReadDma(void *dst, u16 slen) {
return resp;
}
u8 memSpiWrite(void *src) {
u8 memSpiWrite(const void *src) {
u16 i;

446
src/memorypak.c Normal file
View File

@ -0,0 +1,446 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include <libdragon.h>
#include <string.h>
#include <stdio.h>
#include "types.h"
#include "mempak.h"
#include "memorypak.h"
#include "ff.h"
#include "menu.h"
#include "debug.h"
#include "strlib.h"
#include "sys.h"
enum MemoryPakFormat
{
None,
DexDrive,
Z64
};
static uint8_t mempak_data[128 * 256];
char *mempak_path;
char ___TranslateNotes(char *bNote, char *Text)
{
#pragma warning(disable : 4305 4309)
char cReturn = 0x00;
const char aSpecial[] = {0x21, 0x22, 0x23, 0x60, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x3A, 0x3D, 0x3F, 0x40, 0x74, 0xA9, 0xAE};
// { '!' , '\"', '#' , '`' , '*' , '+' , ',' , '-' , '.' , '/' , ':' , '=' , '?' , '>' , 'tm', '(r)','(c)' };
#pragma warning(default : 4305 4309)
int i = 16;
do
{
char b = bNote[i];
if ((b > 0) && i < 32)
{
if (b <= 0x0F) // translate Icons as Spaces
*Text = 0x20;
else if (b <= 0x19) // Numbers
*Text = 0x20 + b;
else if (b <= 0x33) // Characters
*Text = 0x47 + b;
else if (b <= 0x44) // special Symbols
*Text = aSpecial[b - 0x34];
else if (b <= 0x94) // Japan
*Text = 0xC0 + (b % 40);
else // unknown
*Text = (char)0xA4;
++i;
++Text;
}
else
{
*Text = '\0';
if (b)
{
i = 12;
Text = &cReturn;
}
else
i = 13;
}
} while (i != 13);
return cReturn;
}
char ___CountBlocks(char *bMemPakBinary, char *aNoteSizes)
{
int wRemainingBlocks = 123;
char bNextIndex;
int i = 0;
while (i < 16 && wRemainingBlocks <= 123)
{
aNoteSizes[i] = 0;
bNextIndex = bMemPakBinary[0x307 + (i * 0x20)];
while ((bNextIndex >= 5) && (aNoteSizes[i] < wRemainingBlocks))
{
aNoteSizes[i]++;
bNextIndex = bMemPakBinary[0x101 + (bNextIndex * 2)];
}
if (aNoteSizes[i] > wRemainingBlocks)
wRemainingBlocks = 0xFF;
else
wRemainingBlocks -= aNoteSizes[i];
i++;
}
return wRemainingBlocks;
}
//old method to write a file to the mempak at controller 1
int file_to_mpk(display_context_t disp, u8 *filename)
{
enum MemoryPakFormat memorypak_format;
u8 buff[64];
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, filename, FA_READ);
if (result == FR_OK)
{
//int fsize = f_size(&file);
u8 *pch;
pch = strrchr(filename, '.');
sprintf(buff, "%s", (pch + 2));
if (strcmp(buff, "64") == 0)
{
TRACE(disp, "Dexdrive format");
memorypak_format = DexDrive;
//skip header
result = f_lseek (
&file, /* [IN] File object */
4160 /* [IN] File read/write pointer */
);
}
TRACE(disp, "Z64 format");
memorypak_format = Z64;
result =
f_read (
&file, /* [IN] File object */
mempak_data, /* [OUT] Buffer to store read data */
32768, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
f_close(&file);
int err = 0;
for (int j = 0; j < 128; j++)
{
err |= write_mempak_sector(0, j, &mempak_data[j * MEMPAK_BLOCK_SIZE]);
}
}
else
{
memorypak_format = None;
}
return (int)memorypak_format; //TODO: should return enum
}
void view_mpk_file(display_context_t disp, char *mpk_filename)
{
u8 buff[64];
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, mpk_filename, FA_READ);
if (result == FR_OK)
{
//int fsize = f_size(&file);
u8 *pch;
pch = strrchr(mpk_filename, '.');
sprintf(buff, "%s", (pch + 2));
if (strcmp(buff, "64") == 0) //DEXDRIVE format
{
//skip header
result = f_lseek (
&file, /* [IN] File object */
4160 /* [IN] File read/write pointer */
);
}
result =
f_read (
&file, /* [IN] File object */
mempak_data, /* [OUT] Buffer to store read data */
32768, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
f_close(&file);
printText("File contents:", 11, 5, disp);
printText(" ", 11, -1, disp);
int notes_c = 0;
char szBuffer[40],
cAppendix;
int bFirstChar;
int i = 0,
nNotes = 0,
iSum = 0,
iRemainingBlocks;
char aNoteSizes[16];
for (i = 0x10A; i < 0x200; i++)
iSum += mempak_data[i];
if (((iSum % 256) == mempak_data[0x101]))
{
iRemainingBlocks = ___CountBlocks(mempak_data, aNoteSizes);
if (iRemainingBlocks <= 123)
{
for (notes_c = 0; notes_c < 16; notes_c++)
{
if (mempak_data[0x300 + (notes_c * 32)] ||
mempak_data[0x301 + (notes_c * 32)] ||
mempak_data[0x302 + (notes_c * 32)])
{
cAppendix = ___TranslateNotes(&mempak_data[0x300 + (notes_c * 32)], szBuffer);
if (cAppendix != '\0')
sprintf(szBuffer, "%s. %c", szBuffer, cAppendix);
bFirstChar = 1;
for (i = 0; i < (int)strlen(szBuffer); i++)
{
if (szBuffer[i] == ' ')
bFirstChar = 1;
else
{
if (bFirstChar && (szBuffer[i] >= 'a') && (szBuffer[i] <= 'z'))
{
bFirstChar = 0;
szBuffer[i] -= 0x20;
}
}
}
printText(szBuffer, 11, -1, disp);
switch (mempak_data[0x303 + (notes_c * 32)])
{
case 0x00:
sprintf(szBuffer, "None");
break;
case 0x37:
sprintf(szBuffer, "Beta");
break;
case 0x41:
sprintf(szBuffer, "NTSC");
break;
case 0x44:
sprintf(szBuffer, "Germany");
break;
case 0x45:
sprintf(szBuffer, "USA");
break;
case 0x46:
sprintf(szBuffer, "France");
break;
case 0x49:
sprintf(szBuffer, "Italy");
break;
case 0x4A:
sprintf(szBuffer, "Japan");
break;
case 0x50:
sprintf(szBuffer, "Europe");
break;
case 0x53:
sprintf(szBuffer, "Spain");
break;
case 0x55:
sprintf(szBuffer, "Australia");
break;
case 0x58:
case 0x59:
sprintf(szBuffer, "PAL");
break;
default:
sprintf(szBuffer, "Unknown(%02X)", mempak_data[0x303 + (notes_c * 32)]);
}
sprintf(szBuffer, "%i", aNoteSizes[notes_c]);
nNotes++;
}
}
}
int free_c = 0;
for (free_c = nNotes; free_c < 16; free_c++)
printText("[free]", 11, -1, disp);
char buff[512];
printText(" ", 11, -1, disp);
printText("Free space:", 11, -1, disp);
sprintf(buff, "%i blocks", iRemainingBlocks);
printText(buff, 11, -1, disp);
}
else
{
printText("empty", 11, -1, disp);
}
}
}
void view_mpk(display_context_t disp)
{
int err;
printText("Mempak content:", 11, 5, disp);
get_accessories_present();
/* Make sure they don't have a rumble pak inserted instead */
switch (identify_accessory(0))
{
case ACCESSORY_NONE:
printText(" ", 11, -1, disp);
printText("no Mempak", 11, -1, disp);
break;
case ACCESSORY_MEMPAK:
if ((err = validate_mempak(0)))
{
if (err == -3)
{
printText(" ", 11, -1, disp);
printText("not formatted", 11, -1, disp);
}
else
{
printText(" ", 11, -1, disp);
printText("read error", 11, -1, disp);
}
}
else
{
printText(" ", 11, -1, disp);
for (int j = 0; j < 16; j++)
{
entry_structure_t entry;
get_mempak_entry(0, j, &entry);
if (entry.valid)
{
char tmp[512];
sprintf(tmp, "%s", entry.name);
printText(tmp, 11, -1, disp);
}
else
{
printText("[free]", 11, -1, disp);
}
}
char buff[512];
printText(" ", 11, -1, disp);
printText("Free space:", 11, -1, disp);
sprintf(buff, "%d blocks", get_mempak_free_space(0));
printText(buff, 11, -1, disp);
}
break;
case ACCESSORY_RUMBLEPAK:
printText("RumblePak inserted", 11, -1, disp);
break;
default:
break;
}
}
//old function to dump a mempak to a file
void mpk_to_file(display_context_t disp, char *mpk_filename, int quick)
{
u8 buff[64];
u8 v = 0;
u8 ok = 0;
if (quick)
sprintf(buff, "%s%s", mempak_path, mpk_filename);
else
sprintf(buff, "%s%s.MPK", mempak_path, mpk_filename);
FRESULT fr;
FILINFO fno;
fr = f_stat(buff, &fno);
if(fr == FR_OK)
{
printText("File exists", 9, -1, disp);
if (quick)
printText("override", 9, -1, disp);
else
while (fr == FR_OK)
{
sprintf(buff, "%s%s%i.MPK", mempak_path, mpk_filename, v);
fr = f_stat(buff, &fno);
if (fr == FR_OK)
v++;
else
break;
}
}
FRESULT result;
FIL file;
result = f_open(&file, buff, FA_WRITE | FA_OPEN_ALWAYS);
if (result == FR_OK)
{
controller_init();
int err = 0;
for (int j = 0; j < 128; j++)
{
err |= read_mempak_sector(0, j, &mempak_data[j * 256]);
}
UINT bw;
result =
f_write (
&file, /* [IN] Pointer to the file object structure */
mempak_data, /* [IN] Pointer to the data to be written */
32768, /* [IN] Number of bytes to write */
&bw /* [OUT] Pointer to the variable to return number of bytes written */
);
f_close(&file);
sprintf(buff, "File: %s%i.MPK", mpk_filename, v);
printText(buff, 9, -1, disp);
printText("backup done...", 9, -1, disp);
}
}

30
src/menu.c Normal file
View File

@ -0,0 +1,30 @@
#include <libdragon.h>
#include "types.h"
#include "debug.h"
short int gCursorX;
short int gCursorY;
int text_offset = 0;
void printText(char *msg, int x, int y, display_context_t dcon)
{
x = x + text_offset;
if (x != -1)
gCursorX = x;
if (y != -1)
gCursorY = y;
if (dcon)
graphics_draw_text(dcon, gCursorX * 8, gCursorY * 8, msg);
gCursorY++;
if (gCursorY > 29)
{
gCursorY = 0;
gCursorX++;
}
}

32
src/menu_about.c Normal file
View File

@ -0,0 +1,32 @@
#include <libdragon.h>
#include <stdio.h>
#include "types.h"
#include "menu.h"
#include "version.h"
#include "main.h"
#include "everdrive.h"
void menu_about(display_context_t disp)
{
char version_str[32];
char firmware_str[32];
sprintf(version_str, "Altra64: v%s", Altra64_GetVersionString());
printText(version_str, 9, 8, disp);
sprintf(firmware_str, "ED64 firmware: v%03x", evd_getFirmVersion());
printText(firmware_str, 9, -1, disp);
printText("by JonesAlmighty", 9, -1, disp);
printText(" ", 9, -1, disp);
printText("Based on ALT64", 9, -1, disp);
printText("By Saturnu", 9, -1, disp);
printText(" ", 9, -1, disp);
printText("credits to:", 9, -1, disp);
printText("Jay Oster", 9, -1, disp);
printText("Krikzz", 9, -1, disp);
printText("Richard Weick", 9, -1, disp);
printText("ChillyWilly", 9, -1, disp);
printText("ShaunTaylor", 9, -1, disp);
printText("Conle", 9, -1, disp);
}

View File

@ -1,12 +1,17 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <mad.h>
#include "fat.h"
#include "mp3.h"
#include <libdragon.h>
#include <mad.h>
#include "mp3.h"
#include "ff.h"
static struct mad_stream Stream;
static struct mad_header Header;
@ -63,13 +68,11 @@ static int mp3_seek(char* fd, int offset, int whence) {
}
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
FRESULT result;
FILINFO fno;
//TODO: error
result = f_stat (fd, &fno);
mp3File_fsize = fno.fsize;
return mp3File_fsize;
}
@ -77,7 +80,7 @@ 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 ^^
resp = fatOpenFileByName(fname, 0); //err if not found ^^
int fsize = file.sec_available*512; //fsize in bytes
mp3File_fsize = fsize;
@ -91,6 +94,37 @@ static void _f_read(char* fname, unsigned char *readBuffer, int size){
}
//dma_write_s(buffer, 0xb0000000, fsize);
*/
mp3_size(fname);
FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, fname, FA_READ);
if (result == FR_OK)
{
int fsize = f_size(&file);
if ( fsize > size)
{
//todo: set the read pointer
//readBuffer+mp3File_fptr
}
result =
f_read (
&file, /* [IN] File object */
readBuffer, /* [OUT] Buffer to store read data */
size, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
f_close(&file);
mp3File_fptr+=size;
//dma_write_s(buffer, 0xb0000000, fsize);
}
}
static int mp3_read(char* fd, unsigned char *ptr, int size)
@ -153,7 +187,7 @@ static int MP3_SkipHdr(char* fd)
mp3_seek(fd, offset, SEEK_SET);
//now seek for a sync
while(1) {
for ( ;;) {
offset = mp3_seek(fd, 0, SEEK_CUR);
size = mp3_read(fd, buf, sizeof(buf));
@ -327,7 +361,7 @@ static void MP3_GetInfo(long long *samples, int *rate) {
mad_stream_buffer (&stream, localBuffer, red);
while (1) {
for ( ;; ) {
if (mad_header_decode(&header, &stream) == -1) {
if (stream.buffer == NULL || stream.error == MAD_ERROR_BUFLEN) {
break;
@ -359,7 +393,7 @@ static void MP3_GetInfo(long long *samples, int *rate) {
}
void start_mp3(char *fname, long long *samples, int *rate, int *channels) {
void mp3_Start(char *fname, long long *samples, int *rate, int *channels) {
sprintf(mp3Fd, "%s", fname);
//if (mp3Fd[0]!=0)
@ -378,7 +412,7 @@ void start_mp3(char *fname, long long *samples, int *rate, int *channels) {
//*samples = 0;
}
void stop_mp3(void) {
void mp3_Stop(void) {
MP3_Exit();
mp3File_fptr=0;
/*
@ -393,7 +427,7 @@ void stop_mp3(void) {
*/
}
int update_mp3(char *buf, int bytes) {
int mp3_Update(char *buf, int bytes) {
MP3_Callback(buf, bytes/4);
return eos ? 0 : 1;
}

79
src/rom.c Normal file
View File

@ -0,0 +1,79 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include "sram.h"
#include "everdrive.h"
#include "sys.h"
#include "rom.h"
#include "cic.h"
void pif_boot()
{
//TODO: implement
}
int is_valid_rom(unsigned char *buffer) {
/* Test if rom is a native .z64 image with header 0x80371240. [ABCD] */
if((buffer[0]==0x80)&&(buffer[1]==0x37)&&(buffer[2]==0x12)&&(buffer[3]==0x40))
return 0;
/* Test if rom is a byteswapped .v64 image with header 0x37804012. [BADC] */
else if((buffer[0]==0x37)&&(buffer[1]==0x80)&&(buffer[2]==0x40)&&(buffer[3]==0x12))
return 1;
/* Test if rom is a wordswapped .n64 image with header 0x40123780. [DCBA] */
else if((buffer[0]==0x40)&&(buffer[1]==0x12)&&(buffer[2]==0x37)&&(buffer[3]==0x80))
return 2;
else
return 0;
}
void swap_header(unsigned char* header, int loadlength) {
unsigned char temp;
int i;
/* Btyeswap if .v64 image. */
if( header[0]==0x37) {
for (i = 0; i < loadlength; i+=2) {
temp= header[i];
header[i]= header[i+1];
header[i+1]=temp;
}
}
/* Wordswap if .n64 image. */
else if( header[0]==0x40) {
for (i = 0; i < loadlength; i+=4) {
temp= header[i];
header[i]= header[i+3];
header[i+3]=temp;
temp= header[i+1];
header[i+1]= header[i+2];
header[i+2]=temp;
}
}
}
u8 getCicType(u8 bios_cic) {
u8 cic_buff[2048];
volatile u8 cic_chip;
volatile u32 val;
if (bios_cic) {
evd_setCfgBit(ED_CFG_SDRAM_ON, 0);
sleep(10);
val = *(u32 *) 0xB0000170;
dma_read_s(cic_buff, 0xB0000040, 1024);
cic_chip = get_cic(cic_buff);
evd_setCfgBit(ED_CFG_SDRAM_ON, 1);
sleep(10);
}
else {
val = *(u32 *) 0xB0000170;
dma_read_s(cic_buff, 0xB0000040, 1024);
cic_chip = get_cic(cic_buff);
}
return cic_chip;
}

View File

@ -1,37 +1,43 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include <console.h>
#include "disk.h"
#include "types.h"
#include "integer.h"
#include "sd.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 CMD0 (0x40+0) // GO_IDLE_STATE, Software reset.
#define CMD1 (0x40+1) // SEND_OP_COND, Initiate initialization process.
#define CMD2 (0x40+2) //read cid
#define CMD3 (0x40+3) //read rca
#define CMD6 (0x40+6)
#define CMD7 (0x40+7)
#define CMD8 (0x40+8) // SEND_IF_COND, For only SDC V2. Check voltage range.
#define CMD9 (0x40+9) // SEND_CSD, Read CSD register.
#define CMD10 (0x40+10) // SEND_CID, Read CID register.
#define CMD12 (0x40+12) // STOP_TRANSMISSION, Stop to read data.
#define ACMD13 (0xC0+13) // SD_STATUS (SDC)
#define CMD16 (0x40+16) // SET_BLOCKLEN, Change R/W block size.
#define CMD17 (0x40+17) // READ_SINGLE_BLOCK, Read a block.
#define CMD18 (0x40+18) // READ_MULTIPLE_BLOCK, Read multiple blocks.
#define ACMD23 (0xC0+23) // SET_WR_BLK_ERASE_COUNT (SDC)
#define CMD24 (0x40+24) // WRITE_BLOCK, Write a block.
#define CMD25 (0x40+25) // WRITE_MULTIPLE_BLOCK, Write multiple blocks.
#define CMD41 (0x40+41) // SEND_OP_COND (ACMD)
#define ACMD41 (0xC0+41) // SEND_OP_COND (SDC)
#define CMD55 (0x40+55) // APP_CMD, Leading command of ACMD<n> command.
#define CMD58 (0x40+58) // READ_OCR, Read OCR.
#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
@ -46,19 +52,19 @@ u32 disk_interface;
unsigned int diskCrc7(unsigned char *buff, unsigned int len);
void diskCrc16SD(u8 *data, u16 *crc_out, u16 len);
void diskCrc16SD(const 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 diskReadSD(u32 sector, void *buff, u16 count);
u8 diskWriteSD(u32 sector, const u8 *buff, u16 count);
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);
u8 diskReadSPI(u32 sector, void *buff, u16 count);
u8 diskWriteSPI(u32 sector, const u8 *buff, u16 count);
@ -97,17 +103,17 @@ const u16 sd_crc16_table[] = {
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
void diskSetInterface(u32 interface) {
void sdSetInterface(u32 interface) {
disk_interface = interface;
}
u8 diskGetInterface() {
u8 sdGetInterface() {
return disk_interface;
}
u8 diskInit() {
u8 sdInit() {
if (disk_interface == DISK_IFACE_SD) {
return diskInitSD();
@ -116,25 +122,25 @@ u8 diskInit() {
}
}
u8 diskRead(u32 saddr, void *buff, u16 slen) {
u8 sdRead(u32 sector, u8 *buff, u16 count) {
if (disk_interface == DISK_IFACE_SD) {
return diskReadSD(saddr, buff, slen);
return diskReadSD(sector, buff, count);
} else {
return diskReadSPI(saddr, buff, slen);
return diskReadSPI(sector, buff, count);
}
}
u8 diskWrite(u32 saddr, u8 *buff, u16 slen) {
u8 sdWrite(u32 sector, const u8 *buff, u16 count) {
if (disk_interface == DISK_IFACE_SD) {
return diskWriteSD(saddr, buff, slen);
return diskWriteSD(sector, buff, count);
} else {
return diskWriteSPI(saddr, buff, slen);
return diskWriteSPI(sector, buff, count);
}
}
void diskCrc16SD(u8 *data, u16 *crc_out, u16 len) {
void diskCrc16SD(const u8 *data, u16 *crc_out, u16 len) {
///u16 len = 512;
u16 i, tmp1, u;
@ -369,20 +375,20 @@ u8 diskInitSD() {
}
u8 diskReadSD(u32 saddr, void *buff, u16 slen) {
u8 diskReadSD(u32 sector, void *buff, u16 count) {
u8 resp;
if (!(card_type & 1))saddr *= 512;
resp = diskCmdSD(CMD18, saddr);
if (!(card_type & 1))sector *= 512;
resp = diskCmdSD(CMD18, sector);
if (resp)return DISK_ERR_RD1;
resp = memSpiRead(buff, slen);
resp = memSpiRead(buff, count);
if (resp)return resp;
//console_printf("drd: %0X\n", saddr);
//console_printf("drd: %0X\n", sector);
resp = diskStopRwSD();
return resp;
@ -409,24 +415,24 @@ u8 diskStopRwSD() {
return 0;
}
u8 diskWriteSD(u32 saddr, u8 *buff, u16 slen) {
u8 diskWriteSD(u32 sector, const u8 *buff, u16 count) {
u8 resp;
u16 crc16[5];
u16 i;
u16 u;
u8 ram_buff[512];
u8 *buff_ptr;
const u8 *buff_ptr;
if (!(card_type & 1))saddr *= 512;
resp = diskCmdSD(CMD25, saddr);
if (!(card_type & 1))sector *= 512;
resp = diskCmdSD(CMD25, sector);
if (resp)return DISK_ERR_WR1;
evd_SDdatWriteMode(0);
while (slen--) {
while (count--) {
if ((u32) buff >= ROM_ADDR && (u32) buff < ROM_END_ADDR) {
dma_read_s(ram_buff, (u32) buff, 512);
@ -626,17 +632,17 @@ u8 diskInitSPI() {
return 0;
}
u8 diskReadSPI(u32 saddr, void *buff, u16 slen) {
u8 diskReadSPI(u32 sector, void *buff, u16 count) {
u8 resp;
if (!(card_type & 1))saddr *= 512;
resp = diskCmdSPI(CMD18, saddr);
if (!(card_type & 1))sector *= 512;
resp = diskCmdSPI(CMD18, sector);
if (resp != 0)return DISK_ERR_RD1;
memSpiSSOn();
resp = memSpiRead(buff, slen);
resp = memSpiRead(buff, count);
memSpiSSOff();
diskCmdSPI(CMD12, 0);
@ -644,18 +650,18 @@ u8 diskReadSPI(u32 saddr, void *buff, u16 slen) {
return resp;
}
u8 diskWriteSPI(u32 saddr, u8 *buff, u16 slen) {
u8 diskWriteSPI(u32 sector, const u8 *buff, u16 count) {
u8 resp;
u16 i;
if (!(card_type & 1))saddr *= 512;
resp = diskCmdSPI(CMD25, saddr);
if (!(card_type & 1))sector *= 512;
resp = diskCmdSPI(CMD25, sector);
if (resp != 0)return DISK_ERR_WR1;
memSpiSSOn();
while (slen--) {
while (count--) {
mem_spi(0xff);
mem_spi(0xff);

113
src/sound.c Normal file
View File

@ -0,0 +1,113 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#include <mikmod.h>
#include <libdragon.h> //needed for audio_get_frequency()
#include "hashtable.h"
MODULE *moduleBGM = NULL;
/* sound effects */
hashtable* samples = NULL;
/* voices */
SBYTE voiceSFX;
void sndInit(void)
{
samples = hashtable_create();
/* register all the drivers */
MikMod_RegisterAllDrivers();
MikMod_RegisterAllLoaders();
/* initialize the library */
md_mode = 0;
md_mode |= DMODE_16BITS;
md_mode |= DMODE_SOFT_MUSIC;
md_mode |= DMODE_SOFT_SNDFX;
md_mode |= DMODE_INTERP;
md_mixfreq = audio_get_frequency();
MikMod_Init("");
/* reserve 2 voices for sound effects */
MikMod_SetNumVoices(-1, 2);
/* get ready to play */
MikMod_EnableOutput();
}
void sndPlayBGM(char* filename)
{
if (Player_Active())
{
Player_Stop();
}
Player_Free(moduleBGM);
moduleBGM = NULL;
moduleBGM = Player_Load(filename, 64, 0);
if (moduleBGM)
{
Player_Start(moduleBGM);
Player_SetVolume(20);
}
}
void sndStopAll(void)
{
Voice_Stop(voiceSFX);
Player_Stop();
MikMod_DisableOutput();
int index = 0;
while (index < samples->capacity) {
Sample_Free(samples->body[index].value);
index = index + 1;
}
hashtable_destroy(samples);
Player_Free(moduleBGM);
moduleBGM = NULL;
samples = hashtable_create();
//MikMod_Exit(); //I dont think we should ever exit as that would mean reinitialising?!
}
void sndPlaySFX(char* filename)
{
if (!Voice_Stopped(voiceSFX))
{
Voice_Stop(voiceSFX);
}
if (hashtable_get(samples, filename) == NULL)
{
hashtable_set(samples, filename, Sample_Load(filename));
}
//audio_write_silence();
Voice_SetVolume(voiceSFX, 200);
voiceSFX = Sample_Play(hashtable_get(samples, filename), 0, 0);
MikMod_Update(); //force an update so that the voice is registered as playing!
}
void sndUpdate(void)
{
if (!Voice_Stopped(voiceSFX) || Player_Active())
{
MikMod_Update();
}
}

View File

@ -1,10 +1,16 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include <malloc.h>
#include <stdint.h>
#include <string.h>
#include "sys.h"
#include "types.h"
#include "utils.h"
#include "sram.h"
#include "rom.h"
void PI_Init(void) {

158
src/strlib.c Normal file
View File

@ -0,0 +1,158 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include "strlib.h"
#include "types.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); }
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;
}
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++;
}
}
}

View File

@ -1,11 +1,14 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include <stdint.h>
#include <dma.h>
#include <n64sys.h>
#include "sys.h"
#include "types.h"
#include "everdrive.h"
#include "errors.h"
#include "usb.h"
#include "rom.h"
u32 asm_date;
@ -14,33 +17,6 @@ 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];
@ -137,49 +113,8 @@ void dma_write_sram(void* src, u32 offset, u32 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;
}
@ -190,8 +125,6 @@ void clean();
#define MEM32(addr) *((volatile u32 *)addr)
u8 str_buff[128];
u8 STR_intToDecString(u32 val, u8 *str) {
int len;
@ -269,91 +202,4 @@ void STR_intToDecStringMin(u32 val, u8 *str, u8 min_size) {
}
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++;
}
}
}

View File

@ -1,9 +1,11 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include "everdrive.h"
#include "sys.h"
#include "types.h"
#include <libdragon.h>
#include "rom.h"
u8 cmdTest();
@ -83,12 +85,17 @@ u8 usbListener() {
//IO_WRITE(PI_BSD_DOM1_PGS_REG, 0x0c);
//IO_WRITE(PI_BSD_DOM1_PGS_REG, 0x80);
//evdSetESaveType(SAVE_TYPE_EEP16k);
system_cic = CIC_6102;
//system_cic = CIC_6102; //TODO: re-enable
evd_lockRegs();
IO_WRITE(PI_STATUS_REG, 3);
sleep(2);
pif_boot();
break;
case 'D':
//TODO: initiate debug session
break;
default:
break;
}
@ -117,7 +124,7 @@ u8 cmdFill() {
usb_buff8[i] = 0;
}
//console_printf("buff prepared\n");
romFill(0, 0x200000, 0);
//romFill(0, 0x200000, 0); //TODO: re-enable
//console_printf("fill done\n");
usb_buff8[3] = 'k';

View File

@ -1,19 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
//
// Copyright (c) 2017 The Altra64 project contributors
// Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
// See LICENSE file in the project root for full license information.
//
#include <string.h>
#include <stdint.h>
#include <malloc.h>
#include <libdragon.h>
#include <n64sys.h>
#include "everdrive.h"
#include "sys.h"
#include "types.h"
#include "utils.h"
#include "sram.h"
#include "rom.h"
#include "cic.h"
#define STBI_HEADER_FILE_ONLY
#include "stb_image.c"
extern short int gCheats; /* 0 = off, 1 = select, 2 = all */
extern short int force_tv;
@ -22,93 +23,11 @@ extern short int boot_country;
static u8 __attribute__((aligned(16))) dmaBuf[128*1024];
static volatile struct _PI_regs_s * const _PI_regs = (struct _PI_regs_s *)0xa4600000;
int is_valid_rom(unsigned char *buffer) {
/* Test if rom is a native .z64 image with header 0x80371240. [ABCD] */
if((buffer[0]==0x80)&&(buffer[1]==0x37)&&(buffer[2]==0x12)&&(buffer[3]==0x40))
return 0;
/* Test if rom is a byteswapped .v64 image with header 0x37804012. [BADC] */
else if((buffer[0]==0x37)&&(buffer[1]==0x80)&&(buffer[2]==0x40)&&(buffer[3]==0x12))
return 1;
/* Test if rom is a wordswapped .n64 image with header 0x40123780. [DCBA] */
else if((buffer[0]==0x40)&&(buffer[1]==0x12)&&(buffer[2]==0x37)&&(buffer[3]==0x80))
return 2;
else
return 0;
}
void swap_header(unsigned char* header, int loadlength) {
unsigned char temp;
int i;
/* Btyeswap if .v64 image. */
if( header[0]==0x37) {
for (i = 0; i < loadlength; i+=2) {
temp= header[i];
header[i]= header[i+1];
header[i+1]=temp;
}
}
/* Wordswap if .n64 image. */
else if( header[0]==0x40) {
for (i = 0; i < loadlength; i+=4) {
temp= header[i];
header[i]= header[i+3];
header[i+3]=temp;
temp= header[i+1];
header[i+1]= header[i+2];
header[i+2]=temp;
}
}
}
u8 getCicType(u8 bios_cic) {
u8 cic_buff[2048];
volatile u8 cic_chip;
volatile u32 val;
if (bios_cic) {
evd_setCfgBit(ED_CFG_SDRAM_ON, 0);
sleep(10);
val = *(u32 *) 0xB0000170;
dma_read_s(cic_buff, 0xB0000040, 1024);
cic_chip = get_cic(cic_buff);
evd_setCfgBit(ED_CFG_SDRAM_ON, 1);
sleep(10);
}
else {
val = *(u32 *) 0xB0000170;
dma_read_s(cic_buff, 0xB0000040, 1024);
cic_chip = get_cic(cic_buff);
}
return cic_chip;
}
int get_cic(unsigned char *buffer) {
unsigned int crc;
// figure out the CIC
crc = CRC_Calculate(0, buffer, 1000);
switch(crc) {
case 0x303faac9:
case 0xf0da3d50:
return 1;
case 0xf3106101:
return 2;
case 0xe7cd9d51:
return 3;
case 0x7ae65c9:
return 5;
case 0x86015f8f:
return 6;
}
return 2;
}
int get_cic_save(char *cartid, int *cic, int *save) {
// variables
int NUM_CARTS = 137;
int NUM_CARTS = 138;
int i;
//data arrays
@ -181,37 +100,27 @@ int get_cic_save(char *cartid, int *cic, int *save) {
"TN", "TP", "VL", "VY", "W2", "W4", "WL", "WR", "WU", "WX", "XO", "YS",
"YW", "ZL", "ZS", "AB", "BN", "CG", "CX", "CZ", "D6", "DR", "DZ", "OH",
"TB", "TC", "VB", "WI", "4W", "AG", "AY", "DA", "D2", "3D", "F2", "SI",
"HP", "EV", "MG", "GU", "SA", "VP", "A2", "WC"
"HP", "EV", "MG", "GU", "SA", "VP", "A2", "WC", "GF"
};
/*
// Banjo-Tooie (B7) -> if not using Ultra CIC set to sram, because the crack converts ek16/eep (4) -> sram (1)
int saveTypes[] = {
5, 1, 6, 5, 5, 5, 5, 5, 5, 4, 5, 4, 5, 5, 5, 6, 4, 6, 6, 5, 5, 5, 5, 6,
5, 5, 6, 5, 5, 1, 5, 5, 5, 5, 5, 5, 4, 4, 5, 5, 5, 5, 1, 5, 4, 5, 5, 5,
4, 6, 1, 5, 5, 5, 4, 5, 5, 6, 5, 6, 5, 5, 6, 6, 1, 4, 4, 6, 4, 5, 4, 4,
4, 4, 5, 5, 1, 1, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 1, 5, 5, 5, 5, 5, 5,
1, 4, 5, 5, 5, 1, 5, 6, 1, 1, 4, 5, 5, 5, 5, 6, 1, 5, 1, 5, 5, 5, 1, 1,
5, 5, 1, 1, 6, 6, 6, 4, 5, 6, 5, 5, 5, 1, 1, 5
};
*/
// Banjo-Tooie B7 -> set to sram 'cause crk converts ek16->sram
int saveTypes[] = {
2, 1, 5, 1, 3, 1, 1, 3, 3, 3, 3, 3, 3, 5, 3, 5, 3, 3, 3, 4, 5, 4, 4, 3,
2, 1, 5, 1, 3, 1, 4, 3, 3, 3, 3, 3, 3, 5, 3, 5, 3, 3, 3, 4, 5, 4, 4, 3,
3, 3, 3, 4, 3, 3, 4, 3, 3, 1, 3, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3, 3, 1, 3,
5, 3, 3, 3, 5, 4, 1, 3, 3, 3, 5, 3, 3, 4, 3, 4, 3, 3, 4, 4, 1, 5, 5, 4,
5, 3, 5, 5, 5, 5, 3, 3, 1, 1, 3, 4, 3, 3, 3, 3, 5, 3, 3, 3, 5, 1, 3, 3,
3, 3, 3, 3, 1, 5, 3, 3, 3, 1, 3, 4, 1, 1, 5, 3, 3, 3, 3, 4, 1, 3, 1, 3,
3, 3, 1, 1, 3, 3, 1, 1, 4, 4, 4, 5, 3, 4, 3, 3, 3, 1, 1, 3
3, 3, 1, 1, 3, 3, 1, 1, 4, 4, 4, 5, 3, 4, 3, 3, 3, 1, 1, 3, 3
};
//bt cic to 2 pos6 was 5
// Banjo-Tooie (B7) -> if not using Ultra CIC set to 2 instead of 5
int cicTypes[] = {
2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, 5, 5, 2,
2, 2, 2, 2, 2, 3, 5, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, 5, 5, 2,
2, 3, 2, 2, 2, 2, 5, 2, 1, 6, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 3, 2, 3, 2,
3, 2, 2, 2, 2, 2, 2, 2, 5, 2, 3, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 3, 5,
3, 2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
};
// search for cartid
@ -333,7 +242,7 @@ int getSRAM( uint8_t *buffer, int size){
PI_Init();
sleep(1000);
sleep(1000); //TODO: really... 1 second
while (dma_busy()) ;
@ -354,6 +263,7 @@ int getSRAM32( uint8_t *buffer) {
return getSRAM(buffer, SAVE_SIZE_SRAM);
}
//TODO: is this now 96k?
int getSRAM128( uint8_t *buffer) {
return getSRAM(buffer, SAVE_SIZE_SRAM128);
}
@ -524,186 +434,6 @@ void restoreTiming(void) {
IO_WRITE(PI_BSD_DOM2_RLS_REG, 0x03);
}
/*
* Load an image from the rom filesystem, returning a pointer to the
* sprite that hold the image.
*/
sprite_t *loadImageDFS(char *fname) {
int size, x, y, n, fd;
u8 *tbuf;
u8 *ibuf;
sprite_t *sbuf;
fd = dfs_open(fname);
if (fd < 0)
return 0; // couldn't open image
size = dfs_size(fd);
tbuf = malloc(size);
if (!tbuf) {
dfs_close(fd);
return 0; // out of memory
}
dfs_read(tbuf, 1, size, fd);
dfs_close(fd);
ibuf = stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
free(tbuf);
if (!ibuf)
return 0; // couldn't decode image
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 2);
if (!sbuf) {
stbi_image_free(ibuf);
return 0; // out of memory
}
sbuf->width = x;
sbuf->height = y;
sbuf->bitdepth = 2;
sbuf->format = 0;
sbuf->hslices = x / 32;
sbuf->vslices = y / 16;
color_t *src = (color_t*)ibuf;
u16 *dst = (u16*)((u32)sbuf + sizeof(sprite_t));
for (int j=0; j<y; j++)
for (int i=0; i<x; i++)
dst[i + j*x] = graphics_convert_color(src[i + j*x]) & 0x0000FFFF;
/* Invalidate data associated with sprite in cache */
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
stbi_image_free(ibuf);
return sbuf;
}
sprite_t *loadImage32(u8 *png, int size) {
int x, y, n, fd;
u8 *tbuf;
u32 *ibuf;
sprite_t *sbuf;
tbuf = malloc(size);
memcpy(tbuf,png,size);
ibuf = (u32*)stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
free(tbuf);
if (!ibuf)
return 0; // couldn't decode image
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 4);
if (!sbuf) {
stbi_image_free(ibuf);
return 0; // out of memory
}
sbuf->width = x;
sbuf->height = y;
sbuf->bitdepth = 4;
sbuf->format = 0;
sbuf->hslices = x / 32;
sbuf->vslices = y / 32;
// color_t *src = (color_t*)ibuf;
u32 *dst = (u32*)((u32)sbuf + sizeof(sprite_t));
for (int j=0; j<y; j++)
for (int i=0; i<x; i++)
dst[i + j*x] = ibuf[i + j*x];
/* Invalidate data associated with sprite in cache */
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
stbi_image_free(ibuf);
return sbuf;
}
sprite_t *loadImage32DFS(char *fname) {
int size, x, y, n, fd;
u8 *tbuf;
u32 *ibuf;
sprite_t *sbuf;
fd = dfs_open(fname);
if (fd < 0)
return 0; // couldn't open image
size = dfs_size(fd);
tbuf = malloc(size);
if (!tbuf) {
dfs_close(fd);
return 0; // out of memory
}
dfs_read(tbuf, 1, size, fd);
dfs_close(fd);
ibuf = (u32*)stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
free(tbuf);
if (!ibuf)
return 0; // couldn't decode image
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 4);
if (!sbuf) {
stbi_image_free(ibuf);
return 0; // out of memory
}
sbuf->width = x;
sbuf->height = y;
sbuf->bitdepth = 4;
sbuf->format = 0;
sbuf->hslices = x / 32;
sbuf->vslices = y / 32;
// color_t *src = (color_t*)ibuf;
u32 *dst = (u32*)((u32)sbuf + sizeof(sprite_t));
for (int j=0; j<y; j++)
for (int i=0; i<x; i++)
dst[i + j*x] = ibuf[i + j*x];
/* Invalidate data associated with sprite in cache */
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
stbi_image_free(ibuf);
return sbuf;
}
/*
* Draw an image to the screen using the sprite passed.
*/
void drawImage(display_context_t dcon, sprite_t *sprite) {
int x, y = 0;
rdp_sync(SYNC_PIPE);
rdp_set_default_clipping();
rdp_enable_texture_copy();
rdp_attach_display(dcon);
// Draw image
for (int j=0; j<sprite->vslices; j++) {
x = 0;
for (int i=0; i<sprite->hslices; i++) {
rdp_sync(SYNC_PIPE);
rdp_load_texture_stride(0, 0, MIRROR_DISABLED, sprite, j*sprite->hslices + i);
rdp_draw_sprite(0, x, y);
x += 32;
}
y += 16;
}
rdp_detach_display();
}
#define CIC_6101 1
#define CIC_6102 2
#define CIC_6103 3
#define CIC_6104 4
#define CIC_6105 5
#define CIC_6106 6
#define ROM ((vu32 *)0xB0000000)
#define EXE_START 0xB0001000
@ -853,20 +583,20 @@ void simulate_boot(u32 cic_chip, u8 gBootCic, u32 *cheat_lists[2]) {
".byte 0x3F;" // NUS-CIC-6101
".byte 0x3F;" // NUS-CIC-6102
".byte 0x78;" // NUS-CIC-6103
".byte 0x00;" // Unused
".byte 0xAC;" // Unused NUS-CIC-5101 hacked to 4 0xAC seed
".byte 0x91;" // NUS-CIC-6105
".byte 0x85;" // NUS-CIC-6106
".byte 0x00;" // Unused
".byte 0xDD;" // NUS-CIC-5167
"cic_patch_offsets:"
".byte 0x00;" // Unused
".byte 0x30;" // CIC-NUS-6101
".byte 0x2C;" // CIC-NUS-6102
".byte 0x20;" // CIC-NUS-6103
".byte 0x00;" // Unused
".byte 0x30;" // Unused NUS-CIC-5101 hacked to 4 same patch offset like 6101
".byte 0x8C;" // CIC-NUS-6105
".byte 0x60;" // CIC-NUS-6106
".byte 0x00;" // Unused
".byte 0x30;" // NUS-CIC-5167
// These instructions are copied to RSP IMEM; we don't execute them.
"imem_start:"

13
src/version.c Normal file
View File

@ -0,0 +1,13 @@
//
// Copyright (c) 2017 The Altra64 project contributors
// See LICENSE file in the project root for full license information.
//
#include "version.h"
#define ALTRA64_VERSION "0.1.8.6.1.3"
const char* Altra64_GetVersionString(void)
{
return ALTRA64_VERSION;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +0,0 @@
#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); }

21
tools/deploy-sd.sh Normal file
View File

@ -0,0 +1,21 @@
#
# Copyright (c) 2017 The Altra64 project contributors
# Portions (c) 2013 saturnu (Alt64) based on libdragon, Neo64Menu, ED64IO, libn64-hkz, libmikmod
# See LICENSE file in the project root for full license information.
#
#! /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 ../bin/OS64.v64 /mnt/ED64/
sudo cp ../res/ALT64.INI /mnt/ED64/
echo -e "umounting..."
sudo umount /mnt
echo -e "done..."
else
echo -e "File $file doesnt exists - sdcard problem?"
fi

125
tools/extract-firmware.cmd Normal file
View File

@ -0,0 +1,125 @@
::
:: Copyright (c) 2017 The Altra64 project contributors
:: See LICENSE file in the project root for full license information.
::
@echo off
cd ..
set "fs=%cd%\res\filesystem\firmware"
set "lfs=%fs%"
set "drive=%lfs:~0,1%"
set lfs=%lfs:~2%
set "lfs=%lfs:\=/%"
if %drive%==A set "drive=a"
if %drive%==B set "drive=b"
if %drive%==C set "drive=c"
if %drive%==D set "drive=d"
if %drive%==E set "drive=e"
if %drive%==F set "drive=f"
if %drive%==G set "drive=g"
if %drive%==H set "drive=h"
if %drive%==I set "drive=i"
if %drive%==J set "drive=j"
if %drive%==K set "drive=k"
if %drive%==L set "drive=l"
if %drive%==M set "drive=m"
if %drive%==N set "drive=n"
if %drive%==O set "drive=o"
if %drive%==P set "drive=p"
if %drive%==Q set "drive=q"
if %drive%==R set "drive=r"
if %drive%==S set "drive=s"
if %drive%==T set "drive=t"
if %drive%==U set "drive=u"
if %drive%==V set "drive=v"
if %drive%==W set "drive=w"
if %drive%==X set "drive=x"
if %drive%==Y set "drive=y"
if %drive%==Z set "drive=z"
set "lfs=/mnt/%drive%%lfs%"
echo "Windows dir is %fs%"
echo "Linux dir is %lfs%"
:: del old firmware dir in ../res/filesystem
RD /S /Q "%fs%"
:: mk firmware dir in ../res/filesystem
MKDIR "%fs%"
SET "rom=%1"
IF %1.==. (
SET /P rom="Please enter full path to OS64.v64 V2.12:"
)
set "drive=%rom:~0,1%"
set rom=%rom:~2%
set "rom=%rom:\=/%"
if %drive%==A set "drive=a"
if %drive%==B set "drive=b"
if %drive%==C set "drive=c"
if %drive%==D set "drive=d"
if %drive%==E set "drive=e"
if %drive%==F set "drive=f"
if %drive%==G set "drive=g"
if %drive%==H set "drive=h"
if %drive%==I set "drive=i"
if %drive%==J set "drive=j"
if %drive%==K set "drive=k"
if %drive%==L set "drive=l"
if %drive%==M set "drive=m"
if %drive%==N set "drive=n"
if %drive%==O set "drive=o"
if %drive%==P set "drive=p"
if %drive%==Q set "drive=q"
if %drive%==R set "drive=r"
if %drive%==S set "drive=s"
if %drive%==T set "drive=t"
if %drive%==U set "drive=u"
if %drive%==V set "drive=v"
if %drive%==W set "drive=w"
if %drive%==X set "drive=x"
if %drive%==Y set "drive=y"
if %drive%==Z set "drive=z"
set "rom=/mnt/%drive%%rom%"
echo "Linux rom dir is %rom%"
::echo. "This script is not yet ready and will now exit."
::GOTO exit
@echo ON
:: OS64.V64 - Version 2.12 firmware offsets:
:: cart offset (hex) offset (dec) length
:: v2_old 0x25070 151664 61552
:: v2 0x15930 88368 63276
:: v2.5 0x340F0 213232 69911
:: v3 0x45210 283152 71187
:: Count = lengh / blocksize
:: Seek = offset converted to decimal / blocksize
:: ED rev 2_old
bash --verbose -c "dd skip=9479 count=3847 if=%rom% of=%lfs%/firmware_v2_old.bin bs=16"
:: ED rev 2.0 (default should return 0x214)
bash --verbose -c "dd skip=5523 count=3954 if=%rom% of=%lfs%/firmware_v2.bin bs=16"
:: ED rev 2.5 (default should return 0x250)
bash --verbose -c "dd skip=13327 count=4369 if=%rom% of=%lfs%/firmware_v2_5.bin bs=16"
:: ED rev 3 (default should return 0x300)
bash --verbose -c "dd skip=17697 count=4449 if=%rom% of=%lfs%/firmware_v3.bin bs=16"
pause
:exit

51
tools/reset-wsfl.cmd Normal file
View File

@ -0,0 +1,51 @@
::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 2
:: Automatically check & get admin rights
::::::::::::::::::::::::::::::::::::::::::::
@echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:init
setlocal DisableDelayedExpansion
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
"%SystemRoot%\System32\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & pushd .
cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::
@echo on
lxrun /uninstall /full
pause

75
tools/setup-linux.sh Normal file
View File

@ -0,0 +1,75 @@
#
# Copyright (c) 2017 The Altra64 project contributors
# See LICENSE file in the project root for full license information.
#
#!/bin/bash
# Download and install latest updates for the system [sudo req.]
apt-get update
apt-get -y upgrade
# Install essential packages [sudo req.]
apt-get -y install build-essential git texinfo libc6 libgmp-dev libmpfr-dev libmpc-dev libpng-dev zlib1g-dev libtool autoconf
# change to the users root directory
cd ~/
# add a system variable and make it perminent
# echo 'N64_INST=/usr/local/libdragon' >> /etc/environment
# echo 'export N64_INST=/usr/local/libdragon' >> ~/.bashrc
export N64_INST=/usr/local/libdragon
# source ~/.bashrc
# Pull the latest libdragon source code and make a build directory
git clone https://github.com/dragonminded/libdragon.git
# fix issues with the build scripts
sed -i -- 's|${N64_INST:-/usr/local}|/usr/local/libdragon|g' libdragon/tools/build
sed -i -- 's|--with-newlib|--with-newlib --with-system-zlib|g' libdragon/tools/build
sed -i -- 's| -lpng|\nLDLIBS = -lpng|g' libdragon/tools/mksprite/Makefile
sed -i -- 's| -Werror| -w|g' libdragon/tools/mksprite/Makefile
# make a build folder for libdragon
mkdir libdragon/build_gcc
cp libdragon/tools/build libdragon/build_gcc
# run the build script (this will take a while! and if not sudo, will ask for password mid flow!)
cd libdragon/build_gcc
./build
cd ..
# run the install script [sudo req]
make
make install
make tools
make tools-install
cd ..
# install libmikmod (custom version)
git clone https://github.com/networkfusion/libmikmod
cd libmikmod/n64
make
make install
cd .. # we have are in a subfolder, this is not a duplicate...
cd ..
# install libyaml
git clone https://github.com/yaml/libyaml
cd libyaml
./bootstrap
#$(N64_INST) converterd to $N64_INST below otherwise it will not run on WSFL
export PATH=$PATH:$N64_INST/bin
CFLAGS="-std=gnu99 -march=vr4300 -mtune=vr4300" \
LDFLAGS="-L$N64_INST/lib -Tn64ld.x" \
LIBS="-ldragon -lc -ldragonsys -lnosys" \
./configure --host=mips64-elf --prefix=$N64_INST
make
make install
cd ..
# Perform cleanup
apt-get -y autoremove
apt-get autoclean

56
tools/setup-wsfl.cmd Normal file
View File

@ -0,0 +1,56 @@
::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 2
:: Automatically check & get admin rights
::::::::::::::::::::::::::::::::::::::::::::
@echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:init
setlocal DisableDelayedExpansion
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
"%SystemRoot%\System32\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & pushd .
cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::
@echo on
lxrun /install /y
bash -c "echo 'export N64_INST=/usr/local/libdragon' >> ~/.bashrc; source ~/.bashrc"
bash -c "chmod +x ./setup-linux.sh"
bash --verbose -c "source ./setup-linux.sh"
::bash
pause

View File

@ -1,15 +0,0 @@
#! /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

16
usb.h
View File

@ -1,16 +0,0 @@
/*
* 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 */