Merge branch 'master' of ssh://shion.micecat.ath.cx/~ikari/public_html/git/sd2snes
This commit is contained in:
commit
b9d119ada5
Binary file not shown.
Binary file not shown.
@ -100,7 +100,7 @@ FORMAT = ihex
|
||||
TARGET = $(OBJDIR)/sd2snes
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = main.c ff.c utils.c timer.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c filetypes.c
|
||||
SRC = main.c ff.c utils.c timer.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c smc.c filetypes.c
|
||||
|
||||
ifeq ($(CONFIG_UART_DEBUG),y)
|
||||
SRC += uart.c
|
||||
@ -119,8 +119,8 @@ ASRC =
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
# Use s -mcall-prologues when you really need size...
|
||||
#OPT = 2
|
||||
OPT = 3 -finline-functions
|
||||
OPT = s
|
||||
#OPT = 3 -finline-functions
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
|
||||
@ -35,7 +35,7 @@ CONFIG_UART_BAUDRATE=38400
|
||||
CONFIG_UART_BUF_SHIFT=7
|
||||
CONFIG_HARDWARE_NAME=sd2snes
|
||||
CONFIG_SD_AUTO_RETRIES=10
|
||||
#CONFIG_SD_DATACRC=y
|
||||
CONFIG_SD_DATACRC=y
|
||||
CONFIG_EEPROM_SIZE=512
|
||||
CONFIG_EEPROM_OFFSET=512
|
||||
CONFIG_MAX_PARTITIONS=2
|
||||
CONFIG_MAX_PARTITIONS=1
|
||||
|
||||
71
src/crc16.c
71
src/crc16.c
@ -2,59 +2,20 @@
|
||||
* \file stdout
|
||||
* Functions and types for CRC checks.
|
||||
*
|
||||
* Generated on Tue Sep 15 09:32:35 2009,
|
||||
* Generated on Tue Jun 30 23:02:59 2009,
|
||||
* by pycrc v0.7.1, http://www.tty1.net/pycrc/
|
||||
* using the configuration:
|
||||
* Width = 16
|
||||
* Poly = 0x8005
|
||||
* XorIn = 0xffff
|
||||
* XorIn = 0x0000
|
||||
* ReflectIn = True
|
||||
* XorOut = 0xffff
|
||||
* XorOut = 0x0000
|
||||
* ReflectOut = True
|
||||
* Algorithm = table-driven
|
||||
* Algorithm = bit-by-bit-fast
|
||||
* Direct = True
|
||||
*****************************************************************************/
|
||||
#include "crc16.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Static table used for the table_driven implementation.
|
||||
*****************************************************************************/
|
||||
static const crc_t crc_table[256] = {
|
||||
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
|
||||
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
|
||||
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
|
||||
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
|
||||
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
|
||||
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
|
||||
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
|
||||
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
|
||||
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
|
||||
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
|
||||
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
|
||||
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
|
||||
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
|
||||
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
|
||||
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
|
||||
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
|
||||
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
|
||||
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
|
||||
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
|
||||
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
|
||||
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
|
||||
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
|
||||
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
|
||||
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
|
||||
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
|
||||
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
|
||||
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
|
||||
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
|
||||
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
|
||||
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
|
||||
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
|
||||
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
|
||||
};
|
||||
|
||||
#include "crc16.h"
|
||||
/**
|
||||
* Update the crc value with new data.
|
||||
*
|
||||
@ -65,14 +26,26 @@ static const crc_t crc_table[256] = {
|
||||
*****************************************************************************/
|
||||
crc_t crc16_update(crc_t crc, const unsigned char *data, size_t data_len)
|
||||
{
|
||||
unsigned int tbl_idx;
|
||||
unsigned int i;
|
||||
uint8_t bit;
|
||||
unsigned char c;
|
||||
|
||||
while (data_len--) {
|
||||
tbl_idx = (crc ^ *data) & 0xff;
|
||||
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffff;
|
||||
|
||||
data++;
|
||||
c = *data++;
|
||||
for (i = 0x01; i & 0xff; i <<= 1) {
|
||||
bit = (crc & 0x8000 ? 1 : 0);
|
||||
if (c & i) {
|
||||
bit ^= 1;
|
||||
}
|
||||
crc <<= 1;
|
||||
if (bit) {
|
||||
crc ^= 0x8005;
|
||||
}
|
||||
}
|
||||
crc &= 0xffff;
|
||||
}
|
||||
return crc & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
994
src/ff.h
994
src/ff.h
@ -1,547 +1,447 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.07a (C)ChaN, 2009
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is an open source software to implement FAT file system to
|
||||
/ small embedded systems. This is a free software and is opened for education,
|
||||
/ research and commercial developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Configuration Options
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FATFS
|
||||
#define _FATFS
|
||||
|
||||
#define _WORD_ACCESS 0
|
||||
/* The _WORD_ACCESS option defines which access method is used to the word
|
||||
/ data in the FAT structure.
|
||||
/
|
||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned
|
||||
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code efficiency. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||
/ 3: f_lseek is removed in addition to level 2. */
|
||||
|
||||
|
||||
#define _FS_TINY 0
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _DRIVES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512
|
||||
/* Maximum sector size to be handled. (512/1024/2048/4096) */
|
||||
/* 512 for memroy card and hard disk, 1024 for floppy disk, 2048 for MO disk */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
||||
/ drive number and can mount only first primaly partition. When it is set to 1,
|
||||
/ each volume is tied to the partitions listed in Drives[]. */
|
||||
|
||||
|
||||
#define _CODE_PAGE 850
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ When it is non LFN configuration, there is no difference between SBCS code
|
||||
/ pages. When LFN is enabled, the code page must always be set correctly.
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift-JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
/ 1258 - Vietnam
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (max:255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN.
|
||||
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
||||
/ 2: Enable LFN with dynamic working buffer on the caller's STACK.
|
||||
/
|
||||
/ The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
||||
/ a Unicode - OEM code conversion function ff_convert() must be added to
|
||||
/ the project. */
|
||||
|
||||
|
||||
#define _FS_REENTRANT 0
|
||||
#define _TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* Type of sync object used on the OS. */
|
||||
/* e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
|
||||
/ provided synchronization handlers, ff_req_grant, ff_rel_grant,
|
||||
/ ff_del_syncobj and ff_cre_syncobj function to the project. */
|
||||
|
||||
|
||||
|
||||
/* End of configuration options. Do not change followings without care. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multiple sector size */
|
||||
|
||||
#if _MAX_SS == 512
|
||||
#define SS(fs) 512
|
||||
#else
|
||||
#if _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
|
||||
#define SS(fs) ((fs)->s_size)
|
||||
#else
|
||||
#error Sector size must be 512, 1024, 2048 or 4096.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure */
|
||||
|
||||
typedef struct _FATFS {
|
||||
BYTE fs_type; /* FAT sub type */
|
||||
BYTE drive; /* Physical drive number */
|
||||
BYTE csize; /* Number of sectors per cluster */
|
||||
BYTE n_fats; /* Number of FAT copies */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE pad1;
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if _MAX_SS != 512U
|
||||
WORD s_size; /* Sector size */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
BYTE pad2;
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector */
|
||||
#endif
|
||||
DWORD sects_fat; /* Sectors per fat */
|
||||
DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure */
|
||||
|
||||
typedef struct _DIR {
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current index number */
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
DWORD sclust; /* Table start cluster (0:Static table) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File object structure */
|
||||
|
||||
typedef struct _FIL {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE csect; /* Sector address in the cluster */
|
||||
DWORD fptr; /* File R/W pointer */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS];/* File R/W buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* File status structure */
|
||||
|
||||
typedef struct _FILINFO {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
char fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
char *lfname; /* Pointer to the LFN buffer */
|
||||
int lfsize; /* Size of LFN buffer [bytes] */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* DBCS code ranges */
|
||||
|
||||
#if _CODE_PAGE == 932 /* CP932 (Japanese Shift-JIS) */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* CP936 (Simplified Chinese GBK) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* CP949 (Korean) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* CP950 (Traditional Chinese Big5) */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#else /* SBCS code pages */
|
||||
#define _DF1S 0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Character code support macros */
|
||||
|
||||
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
||||
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
||||
#define IsDigit(c) (((c)>='0')&&((c)<='9'))
|
||||
|
||||
#if _DF1S /* DBCS configuration */
|
||||
|
||||
#if _DF2S /* Two 1st byte areas */
|
||||
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
||||
#else /* One 1st byte area */
|
||||
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
||||
#endif
|
||||
|
||||
#if _DS3S /* Three 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
||||
#else /* Two 2nd byte areas */
|
||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
||||
#endif
|
||||
|
||||
#else /* SBCS configuration */
|
||||
|
||||
#define IsDBCS1(c) 0
|
||||
#define IsDBCS2(c) 0
|
||||
|
||||
#endif /* _DF1S */
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multi partition */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
|
||||
typedef struct _PARTITION {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
|
||||
extern
|
||||
const PARTITION Drives[]; /* Logical drive# to physical location conversion table */
|
||||
#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */
|
||||
#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
|
||||
#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */
|
||||
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* 0 */
|
||||
FR_DISK_ERR, /* 1 */
|
||||
FR_INT_ERR, /* 2 */
|
||||
FR_NOT_READY, /* 3 */
|
||||
FR_NO_FILE, /* 4 */
|
||||
FR_NO_PATH, /* 5 */
|
||||
FR_INVALID_NAME, /* 6 */
|
||||
FR_DENIED, /* 7 */
|
||||
FR_EXIST, /* 8 */
|
||||
FR_INVALID_OBJECT, /* 9 */
|
||||
FR_WRITE_PROTECTED, /* 10 */
|
||||
FR_INVALID_DRIVE, /* 11 */
|
||||
FR_NOT_ENABLED, /* 12 */
|
||||
FR_NO_FILESYSTEM, /* 13 */
|
||||
FR_MKFS_ABORTED, /* 14 */
|
||||
FR_TIMEOUT /* 15 */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
|
||||
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const char*); /* Create a new directory */
|
||||
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const char*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||
|
||||
#if _USE_STRFUNC
|
||||
int f_putc (int, FIL*); /* Put a character to the file */
|
||||
int f_puts (const char*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */
|
||||
char* f_gets (char*, int, FIL*); /* Get a string from the file */
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#ifndef EOF
|
||||
#define EOF -1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* User defined functions */
|
||||
|
||||
/* Real time clock */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
|
||||
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
|
||||
#endif
|
||||
|
||||
/* Unicode - OEM code conversion */
|
||||
#if _USE_LFN
|
||||
WCHAR ff_convert (WCHAR, UINT);
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
|
||||
BOOL ff_del_syncobj(_SYNC_t);
|
||||
BOOL ff_req_grant(_SYNC_t);
|
||||
void ff_rel_grant(_SYNC_t);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#if _FS_READONLY == 0
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* FatFs refers the members in the FAT structures with byte offset instead
|
||||
/ of structure member because there are incompatibility of the packing option
|
||||
/ between various compilers. */
|
||||
|
||||
#define BS_jmpBoot 0
|
||||
#define BS_OEMName 3
|
||||
#define BPB_BytsPerSec 11
|
||||
#define BPB_SecPerClus 13
|
||||
#define BPB_RsvdSecCnt 14
|
||||
#define BPB_NumFATs 16
|
||||
#define BPB_RootEntCnt 17
|
||||
#define BPB_TotSec16 19
|
||||
#define BPB_Media 21
|
||||
#define BPB_FATSz16 22
|
||||
#define BPB_SecPerTrk 24
|
||||
#define BPB_NumHeads 26
|
||||
#define BPB_HiddSec 28
|
||||
#define BPB_TotSec32 32
|
||||
#define BS_55AA 510
|
||||
|
||||
#define BS_DrvNum 36
|
||||
#define BS_BootSig 38
|
||||
#define BS_VolID 39
|
||||
#define BS_VolLab 43
|
||||
#define BS_FilSysType 54
|
||||
|
||||
#define BPB_FATSz32 36
|
||||
#define BPB_ExtFlags 40
|
||||
#define BPB_FSVer 42
|
||||
#define BPB_RootClus 44
|
||||
#define BPB_FSInfo 48
|
||||
#define BPB_BkBootSec 50
|
||||
#define BS_DrvNum32 64
|
||||
#define BS_BootSig32 66
|
||||
#define BS_VolID32 67
|
||||
#define BS_VolLab32 71
|
||||
#define BS_FilSysType32 82
|
||||
|
||||
#define FSI_LeadSig 0
|
||||
#define FSI_StrucSig 484
|
||||
#define FSI_Free_Count 488
|
||||
#define FSI_Nxt_Free 492
|
||||
|
||||
#define MBR_Table 446
|
||||
|
||||
#define DIR_Name 0
|
||||
#define DIR_Attr 11
|
||||
#define DIR_NTres 12
|
||||
#define DIR_CrtTime 14
|
||||
#define DIR_CrtDate 16
|
||||
#define DIR_FstClusHI 20
|
||||
#define DIR_WrtTime 22
|
||||
#define DIR_WrtDate 24
|
||||
#define DIR_FstClusLO 26
|
||||
#define DIR_FileSize 28
|
||||
#define LDIR_Ord 0
|
||||
#define LDIR_Attr 11
|
||||
#define LDIR_Type 12
|
||||
#define LDIR_Chksum 13
|
||||
#define LDIR_FstClusLO 26
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _FATFS */
|
||||
/*--------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.06 (C)ChaN, 2008
|
||||
/---------------------------------------------------------------------------/
|
||||
/ FatFs module is an experimenal project to implement FAT file system to
|
||||
/ cheap microcontrollers. This is a free software and is opened for education,
|
||||
/ research and development under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2008, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is no warranty.
|
||||
/ * You can use, modify and/or redistribute it for personal, non-profit or
|
||||
/ * commercial use without any restriction under your responsibility.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
|
||||
#define _MCU_ENDIAN 1
|
||||
/* The _MCU_ENDIAN defines which access method is used to the FAT structure.
|
||||
/ 1: Enable word access.
|
||||
/ 2: Disable word access and use byte-by-byte access instead.
|
||||
/ When the architectural byte order of the MCU is big-endian and/or address
|
||||
/ miss-aligned access results incorrect behavior, the _MCU_ENDIAN must be set
|
||||
/ to 2. If it is not the case, it can be set to 1 for good code efficiency. */
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||
/ 3: f_lseek is removed in addition to level 2. */
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
#define _DRIVES 1
|
||||
/*MAX_DRIVES*/
|
||||
/* Number of physical drives to be used. This affects the size of internal
|
||||
* table. (when using _USE_DRIVE_PREFIX */
|
||||
|
||||
#define _USE_MKFS 0
|
||||
/* When _USE_MKFS is set to 1 and _FS_READONLY is set to 0, f_mkfs function is
|
||||
/ enabled. */
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* When _MULTI_PARTITION is set to 0, each logical drive is bound to the same
|
||||
/ physical drive number and can mount only 1st primary partition.
|
||||
/
|
||||
/ When it is set to 1, the low _PARTITION_MASK bits of each partition represent
|
||||
/ the partition and the high (8-_PARTITION_MASK) bits represent the physical
|
||||
/ drive */
|
||||
|
||||
#define _PARTITION_MASK 4
|
||||
|
||||
#define _USE_FSINFO 1
|
||||
/* To enable FSInfo support on FAT32 volume, set _USE_FSINFO to 1. */
|
||||
|
||||
#define _USE_SJIS 0
|
||||
/* When _USE_SJIS is set to 1, Shift-JIS code transparency is enabled, otherwise
|
||||
/ only US-ASCII(7bit) code can be accepted as file/directory name. */
|
||||
|
||||
#define _USE_NTFLAG 0
|
||||
/* When _USE_NTFLAG is set to 1, upper/lower case of the file name is preserved.
|
||||
/ Note that the files are always accessed in case insensitive. */
|
||||
|
||||
#define _USE_CHDIR 0
|
||||
|
||||
#define _USE_CURR_DIR 1
|
||||
|
||||
#define _USE_LFN 1
|
||||
|
||||
/* Maximum number of characters to return for a LFN */
|
||||
/* The buffer used for FILINFO.lfn must be at least */
|
||||
/* _MAX_LFN_LENGTH+1 characters long! */
|
||||
/* Note that if _USE_LFN_DBCS is set, this value */
|
||||
/* represents the characters needed, not bytes */
|
||||
#define _MAX_LFN_LENGTH 255
|
||||
|
||||
/* When _USE_LFN_DBCS is set to 1, FILINFO.lfn will contain a DBCS string, not
|
||||
/ a simple ASCII string */
|
||||
#define _USE_LFN_DBCS 0
|
||||
|
||||
/* When set to 1, All FIL objects will use the buffer. This reduces memory
|
||||
/ requirements as open files will only require space for a FIL object, but
|
||||
/ operate slower. When set, ff.c will behave like tff.c, but will allow
|
||||
/ multiple filesystems. */
|
||||
#define _USE_FS_BUF 1
|
||||
|
||||
/* When set to 1, All objects will use a static buffer. This reduces memory
|
||||
/ requirements to the absolute minimum ~512 bytes for the buffer, but will
|
||||
/ operate slower. This option can only be set if _USE_FS_BUF is set. */
|
||||
#define _USE_1_BUF 1
|
||||
|
||||
/* If set to 1, FatFs will manage the FATFS structures after mounting. If
|
||||
/ set to 0, the caller must send the correct drive FATFS structure for each
|
||||
/ call. Normally, this should be set to 1, but if the caller wants to use
|
||||
/ low level l_* functions or skip sending the drive number in the path string,
|
||||
/ this must be turned off. */
|
||||
#define _USE_DRIVE_PREFIX 1
|
||||
|
||||
/* If set to 1, FatFS will delay mounting the drive until first use. Normally,
|
||||
/ this should be turned on. However, it cannot be used with
|
||||
/ _USE_DRIVE_PREFIX = 0 */
|
||||
#define _USE_DEFERRED_MOUNT 0
|
||||
|
||||
/* New features in 0.05a, not required yet */
|
||||
#define _USE_TRUNCATE 0
|
||||
#define _USE_UTIME 0
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
#if _USE_LFN_DBCS != 0
|
||||
#define S_LFN_OFFSET 26
|
||||
#define S_LFN_INCREMENT 2
|
||||
#else
|
||||
#define S_LFN_OFFSET 13
|
||||
#define S_LFN_INCREMENT 1
|
||||
#endif
|
||||
|
||||
/* Definitions corresponds to multiple sector size (not tested) */
|
||||
#define S_MAX_SIZ 512U /* Do not change */
|
||||
#if S_MAX_SIZ > 512U
|
||||
#define SS(fs) ((fs)->s_size)
|
||||
#else
|
||||
#define SS(fs) 512U
|
||||
#endif
|
||||
|
||||
#if _USE_1_BUF == 1 && _USE_FS_BUF == 0
|
||||
#error You can only use 1_BUF with _USE_FS_BUF at present
|
||||
#define _USE_1_BUF 0
|
||||
#endif
|
||||
|
||||
typedef struct _BUF {
|
||||
DWORD sect;
|
||||
BYTE dirty; /* dirty flag (1:must be written back) */
|
||||
//BYTE pad1;
|
||||
#if _USE_1_BUF != 0
|
||||
struct _FATFS *fs;
|
||||
#endif
|
||||
BYTE data[S_MAX_SIZ]; /* Disk access window for Directory/FAT */
|
||||
} BUF;
|
||||
|
||||
/* File system object structure */
|
||||
typedef struct _FATFS {
|
||||
//WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries */
|
||||
DWORD sects_fat; /* Sectors per fat */
|
||||
DWORD max_clust; /* Maximum cluster# + 1 */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (cluster# for FAT32) */
|
||||
DWORD database; /* Data start sector */
|
||||
#if _USE_CHDIR != 0 || _USE_CURR_DIR != 0
|
||||
DWORD curr_dir;
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
#if _USE_FSINFO
|
||||
DWORD fsi_sector; /* fsinfo sector */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
//BYTE pad2;
|
||||
#endif
|
||||
#endif
|
||||
BYTE fs_type; /* FAT sub type */
|
||||
BYTE csize; /* Number of sectors per cluster */
|
||||
#if S_MAX_SIZ > 512U
|
||||
WORD s_size; /* Sector size */
|
||||
#endif
|
||||
BYTE n_fats; /* Number of FAT copies */
|
||||
BYTE drive; /* Physical drive number */
|
||||
#if _USE_1_BUF == 0
|
||||
BUF buf;
|
||||
#endif
|
||||
} FATFS;
|
||||
|
||||
/* Directory object structure */
|
||||
typedef struct _DIR {
|
||||
//WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current index */
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
DWORD sclust; /* Start cluster */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
} DIR;
|
||||
|
||||
|
||||
/* File object structure */
|
||||
typedef struct _FIL {
|
||||
//WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE csect; /* Sector address in the cluster */
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
DWORD fptr; /* File R/W pointer */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD curr_sect; /* Current sector */
|
||||
#if _FS_READONLY == 0
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_LESS_BUF == 0 && _USE_1_BUF == 0
|
||||
BUF buf; /* File R/W buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
/* File status structure */
|
||||
typedef struct _FILINFO {
|
||||
DWORD fsize; /* Size */
|
||||
WORD fdate; /* Date */
|
||||
WORD ftime; /* Time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
DWORD clust; /* Start cluster */
|
||||
UCHAR fname[8+1+3+1]; /* Name (8.3 format) */
|
||||
#if _USE_LFN != 0
|
||||
UCHAR* lfn;
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* Definitions corresponds to multi partition */
|
||||
|
||||
#if _MULTI_PARTITION != 0 /* Multiple partition cfg */
|
||||
|
||||
#define LD2PD(drv) (drv >> (8-_PARTITION_MASK)) /* Get physical drive# */
|
||||
#define LD2PT(drv) (drv & ((1<<_PARTITION_MASK)-1)) /* Get partition# */
|
||||
#define _LOGICAL_DRIVES (_DRIVES * (1<<_PARTITION_MASK))
|
||||
|
||||
#else /* Single partition cfg */
|
||||
|
||||
#define LD2PD(drv) (drv) /* Physical drive# is equal to logical drive# */
|
||||
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
|
||||
#define _LOGICAL_DRIVES _DRIVES
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* 0 */
|
||||
FR_NOT_READY, /* 1 */
|
||||
FR_NO_FILE, /* 2 */
|
||||
FR_NO_PATH, /* 3 */
|
||||
FR_INVALID_NAME, /* 4 */
|
||||
FR_INVALID_DRIVE, /* 5 */
|
||||
FR_DENIED, /* 6 */
|
||||
FR_EXIST, /* 7 */
|
||||
FR_RW_ERROR, /* 8 */
|
||||
FR_WRITE_PROTECTED, /* 9 */
|
||||
FR_NOT_ENABLED, /* 10 */
|
||||
FR_NO_FILESYSTEM, /* 11 */
|
||||
FR_INVALID_OBJECT, /* 12 */
|
||||
FR_MKFS_ABORTED, /* 13 */
|
||||
FR_IS_DIRECTORY, /* 13 */
|
||||
FR_IS_READONLY, /* 14 */
|
||||
FR_DIR_NOT_EMPTY, /* 15 */
|
||||
FR_NOT_DIRECTORY /* 16 */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
#if _USE_DRIVE_PREFIX == 0
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FATFS*, FIL*, const UCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (FATFS*, DIR*, const UCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (FATFS*, const UCHAR*, FILINFO*); /* Get file status */
|
||||
FRESULT f_getfree (FATFS*, const UCHAR*, DWORD*); /* Get number of free clusters on the drive */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (FATFS*, const UCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (FATFS*, const UCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (FATFS*, const UCHAR*, BYTE, BYTE); /* Change file/dir attriburte */
|
||||
FRESULT f_rename (FATFS*, const UCHAR*, const UCHAR*); /* Rename/Move a file or directory */
|
||||
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||
FRESULT f_chdir (FATFS*, const UCHAR*); /* Change current directory */
|
||||
|
||||
#else
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const UCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const UCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const UCHAR*, FILINFO*); /* Get file status */
|
||||
FRESULT f_getfree (const UCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const UCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const UCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (const UCHAR*, BYTE, BYTE); /* Change file/dir attriburte */
|
||||
FRESULT f_rename (const UCHAR*, const UCHAR*); /* Rename/Move a file or directory */
|
||||
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||
FRESULT f_chdir (const UCHAR*); /* Change current directory */
|
||||
|
||||
#endif
|
||||
|
||||
/* Low Level functions */
|
||||
FRESULT l_opendir(FATFS* fs, DWORD cluster, DIR *dirobj); /* Open an existing directory by its start cluster */
|
||||
FRESULT l_opencluster(FATFS *fs, FIL *fp, DWORD clust); /* Open a cluster by number as a read-only file */
|
||||
FRESULT l_getfree (FATFS*, const UCHAR*, DWORD*, DWORD); /* Get number of free clusters on the drive, limited */
|
||||
|
||||
#if _USE_STRFUNC
|
||||
#define feof(fp) ((fp)->fptr == (fp)->fsize)
|
||||
#define EOF -1
|
||||
int fputc (int, FIL*); /* Put a character to the file */
|
||||
int fputs (const char*, FIL*); /* Put a string to the file */
|
||||
int fprintf (FIL*, const char*, ...); /* Put a formatted string to the file */
|
||||
char* fgets (char*, int, FIL*); /* Get a string from the file */
|
||||
#endif
|
||||
|
||||
/* User defined function to give a current time to fatfs module */
|
||||
|
||||
#if CONFIG_RTC_VARIANT > 0
|
||||
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
|
||||
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
|
||||
#else
|
||||
/* Fixed time: 1982-08-31 0:00:00, same month as the introduction of the C64 */
|
||||
# define get_fattime() 0x51f0000
|
||||
#endif
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#if _FS_READONLY == 0
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
|
||||
/* Offset of FAT structure members */
|
||||
|
||||
#define BS_jmpBoot 0
|
||||
#define BS_OEMName 3
|
||||
#define BPB_BytsPerSec 11
|
||||
#define BPB_SecPerClus 13
|
||||
#define BPB_RsvdSecCnt 14
|
||||
#define BPB_NumFATs 16
|
||||
#define BPB_RootEntCnt 17
|
||||
#define BPB_TotSec16 19
|
||||
#define BPB_Media 21
|
||||
#define BPB_FATSz16 22
|
||||
#define BPB_SecPerTrk 24
|
||||
#define BPB_NumHeads 26
|
||||
#define BPB_HiddSec 28
|
||||
#define BPB_TotSec32 32
|
||||
#define BS_55AA 510
|
||||
|
||||
#define BS_DrvNum 36
|
||||
#define BS_BootSig 38
|
||||
#define BS_VolID 39
|
||||
#define BS_VolLab 43
|
||||
#define BS_FilSysType 54
|
||||
|
||||
#define BPB_FATSz32 36
|
||||
#define BPB_ExtFlags 40
|
||||
#define BPB_FSVer 42
|
||||
#define BPB_RootClus 44
|
||||
#define BPB_FSInfo 48
|
||||
#define BPB_BkBootSec 50
|
||||
#define BS_DrvNum32 64
|
||||
#define BS_BootSig32 66
|
||||
#define BS_VolID32 67
|
||||
#define BS_VolLab32 71
|
||||
#define BS_FilSysType32 82
|
||||
|
||||
#define FSI_LeadSig 0
|
||||
#define FSI_StrucSig 484
|
||||
#define FSI_Free_Count 488
|
||||
#define FSI_Nxt_Free 492
|
||||
|
||||
#define MBR_Table 446
|
||||
|
||||
#define DIR_Name 0
|
||||
#define DIR_Attr 11
|
||||
#define DIR_NTres 12
|
||||
#define DIR_Chksum 13
|
||||
#define DIR_CrtTime 14
|
||||
#define DIR_CrtDate 16
|
||||
#define DIR_FstClusHI 20
|
||||
#define DIR_WrtTime 22
|
||||
#define DIR_WrtDate 24
|
||||
#define DIR_FstClusLO 26
|
||||
#define DIR_FileSize 28
|
||||
|
||||
|
||||
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _MCU_ENDIAN == 1 /* Use word access */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#elif _MCU_ENDIAN == 2 /* Use byte-by-byte access */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(volatile BYTE*)((ptr)+1)<<8)|(WORD)*(volatile BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(volatile BYTE*)((ptr)+3)<<24)|((DWORD)*(volatile BYTE*)((ptr)+2)<<16)|((WORD)*(volatile BYTE*)((ptr)+1)<<8)|*(volatile BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(volatile BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(volatile BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#else
|
||||
#error Do not forget to set _MCU_ENDIAN properly!
|
||||
#endif
|
||||
|
||||
#define _FATFS
|
||||
#endif /* _FATFS */
|
||||
|
||||
@ -6,12 +6,16 @@
|
||||
#include "ff.h"
|
||||
#include "fileops.h"
|
||||
|
||||
WCHAR ff_convert(WCHAR w, UINT dir) {
|
||||
return w;
|
||||
}
|
||||
|
||||
void file_init() {
|
||||
f_mount(0, &fatfs);
|
||||
}
|
||||
|
||||
void file_open(char* filename, BYTE flags) {
|
||||
file_res = f_open(&file_handle, filename, flags);
|
||||
file_res = f_open(&file_handle, (unsigned char*)filename, flags);
|
||||
}
|
||||
|
||||
void file_close() {
|
||||
|
||||
@ -40,15 +40,16 @@
|
||||
#include "uart.h"
|
||||
#include "sdcard.h"
|
||||
#include "diskio.h"
|
||||
#include "integer.h"
|
||||
#include "ff.h"
|
||||
#include "fileops.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "spi.h"
|
||||
#include "avrcompat.h"
|
||||
|
||||
DWORD get_fattime(void) {
|
||||
/*DWORD get_fattime(void) {
|
||||
return 0L;
|
||||
}
|
||||
}*/
|
||||
void set_prog_b(uint8_t val) {
|
||||
if(val) {
|
||||
PORTD |= _BV(PD3);
|
||||
|
||||
@ -17,6 +17,7 @@ typedef uint8_t BYTE;
|
||||
typedef int16_t SHORT;
|
||||
typedef uint16_t USHORT;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint16_t WCHAR;
|
||||
|
||||
/* These types are assumed as 32-bit integer */
|
||||
typedef int32_t LONG;
|
||||
|
||||
39
src/main.c
39
src/main.c
@ -47,8 +47,7 @@
|
||||
#include "fpga_spi.h"
|
||||
#include "spi.h"
|
||||
#include "avrcompat.h"
|
||||
|
||||
char stringbuf[100];
|
||||
#include "filetypes.h"
|
||||
|
||||
/* Make sure the watchdog is disabled as soon as possible */
|
||||
/* Copy this code to your bootloader if you use one and your */
|
||||
@ -131,7 +130,7 @@ int main(void) {
|
||||
|
||||
snes_reset(1);
|
||||
uart_init();
|
||||
// sei(); // interrupts are bad for now, resets the poor AVR when inserting SD card
|
||||
sei(); // suspected to reset the AVR when inserting an SD card
|
||||
_delay_ms(100);
|
||||
disk_init();
|
||||
snes_init();
|
||||
@ -140,7 +139,6 @@ int main(void) {
|
||||
uart_putcrlf();
|
||||
|
||||
file_init();
|
||||
|
||||
FATFS fatfs;
|
||||
f_mount(0,&fatfs);
|
||||
set_busy_led(1);
|
||||
@ -160,12 +158,29 @@ int main(void) {
|
||||
uart_putc('[');
|
||||
load_sram("/test.srm");
|
||||
uart_putc(']');
|
||||
*fs_path=0;
|
||||
uint16_t curr_dir_id = scan_dir(fs_path, 0); // generate files footprint
|
||||
dprintf("curr dir id = %x\n", curr_dir_id);
|
||||
uint16_t saved_dir_id;
|
||||
if((get_db_id(&saved_dir_id) != FR_OK) // no database?
|
||||
|| saved_dir_id != curr_dir_id) { // files changed?
|
||||
dprintf("saved dir id = %x\n", saved_dir_id);
|
||||
_delay_ms(50);
|
||||
dprintf("rebuilding database...");
|
||||
_delay_ms(50);
|
||||
curr_dir_id = scan_dir(fs_path, 1); // then rebuild database
|
||||
sram_writeblock(&curr_dir_id, 0x600000, 2);
|
||||
save_sram("/sd2snes/sd2snes.db", 0x10000, 0x600000);
|
||||
dprintf("done\n");
|
||||
}
|
||||
|
||||
set_busy_led(0);
|
||||
set_avr_ena(1);
|
||||
_delay_ms(100);
|
||||
uart_puts_P(PSTR("SNES GO!"));
|
||||
uart_puts_P(PSTR("SNES GO!\n"));
|
||||
snes_reset(0);
|
||||
|
||||
|
||||
|
||||
while(1) {
|
||||
snes_main_loop();
|
||||
}
|
||||
@ -173,14 +188,8 @@ int main(void) {
|
||||
|
||||
/* HERE BE LIONS */
|
||||
while(1) {
|
||||
SPI_SS_HIGH();
|
||||
FPGA_SS_LOW();
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x00);
|
||||
spiTransferByte(0x7f);
|
||||
spiTransferByte(0xc0);
|
||||
FPGA_SS_HIGH();
|
||||
FPGA_SS_LOW();
|
||||
set_avr_addr(0x600000);
|
||||
spi_fpga();
|
||||
spiTransferByte(0x81); // read w/ increment... hopefully
|
||||
spiTransferByte(0x00); // 1 dummy read
|
||||
uart_putcrlf();
|
||||
@ -202,7 +211,7 @@ while(1) {
|
||||
}
|
||||
// set_avr_bank(3);
|
||||
}
|
||||
FPGA_SS_HIGH();
|
||||
spi_sd();
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
13
src/memory.c
13
src/memory.c
@ -14,32 +14,32 @@
|
||||
#include "fpga_spi.h"
|
||||
#include "avrcompat.h"
|
||||
#include "led.h"
|
||||
#include "filetypes.h"
|
||||
#include "smc.h"
|
||||
#include "fpga_spi.h"
|
||||
|
||||
char* hex = "0123456789ABCDEF";
|
||||
|
||||
void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
uint16_t count=size;
|
||||
void* tgt = buf;
|
||||
uint8_t* tgt = buf;
|
||||
set_avr_addr(addr);
|
||||
spi_fpga();
|
||||
spiTransferByte(0x81); // READ
|
||||
spiTransferByte(0x00); // dummy
|
||||
while(count--) {
|
||||
*((uint8_t*)tgt++) = spiTransferByte(0x00);
|
||||
*(tgt++) = spiTransferByte(0x00);
|
||||
}
|
||||
spi_sd();
|
||||
}
|
||||
|
||||
void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
uint16_t count=size;
|
||||
void* src = buf;
|
||||
uint8_t* src = buf;
|
||||
set_avr_addr(addr);
|
||||
spi_fpga();
|
||||
spiTransferByte(0x91); // WRITE
|
||||
while(count--) {
|
||||
spiTransferByte(*((uint8_t*)src++));
|
||||
spiTransferByte(*src++);
|
||||
}
|
||||
spiTransferByte(0x00); // dummy
|
||||
spi_sd();
|
||||
@ -157,6 +157,9 @@ void save_sram(char* filename, uint32_t sram_size, uint32_t base_addr) {
|
||||
}
|
||||
spi_sd();
|
||||
num = file_write();
|
||||
if(file_res) {
|
||||
uart_putc(0x30+file_res);
|
||||
}
|
||||
}
|
||||
file_close();
|
||||
}
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
#define MEMORY_H
|
||||
uint32_t load_rom(char* filename);
|
||||
uint32_t load_sram(char* filename);
|
||||
void sram_readblock(void* buf, uint32_t addr, uint16_t size);
|
||||
void sram_writeblock(void* buf, uint32_t addr, uint16_t size);
|
||||
void save_sram(char* filename, uint32_t sram_size, uint32_t base_addr);
|
||||
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
|
||||
#endif
|
||||
|
||||
111
src/smc.c
Normal file
111
src/smc.c
Normal file
@ -0,0 +1,111 @@
|
||||
// insert cool lengthy disclaimer here
|
||||
// filetypes.c: File support
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "fileops.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "smc.h"
|
||||
|
||||
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
|
||||
uint8_t countAllASCII(uint8_t* data, int size) {
|
||||
uint8_t res = 0;
|
||||
do {
|
||||
size--;
|
||||
if(data[size] >= 0x20 && data[size] <= 0x7e) {
|
||||
res++;
|
||||
}
|
||||
} while (size);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t countAllJISX0201(uint8_t* data, int size) {
|
||||
uint8_t res = 0;
|
||||
do {
|
||||
size--;
|
||||
if((data[size] >= 0x20 && data[size] <= 0x7e)
|
||||
||(data[size] >= 0xa1 && data[size] <= 0xdf)) {
|
||||
res++;
|
||||
}
|
||||
} while (size);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t isFixed(uint8_t* data, int size, uint8_t value) {
|
||||
uint8_t res = 1;
|
||||
do {
|
||||
size--;
|
||||
if(data[size] != value) {
|
||||
res = 0;
|
||||
}
|
||||
} while (size);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t checkChksum(uint16_t cchk, uint16_t chk) {
|
||||
uint32_t sum = cchk + chk;
|
||||
uint8_t res = 0;
|
||||
if(sum==0x0000ffff) {
|
||||
res = 0x10;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void smc_id(snes_romprops_t* props) {
|
||||
uint8_t score, maxscore=1, score_idx=0;
|
||||
|
||||
snes_header_t* header = &(props->header);
|
||||
|
||||
for(uint8_t num = 0; num < 6; num++) {
|
||||
file_readblock(header, hdr_addr[num], sizeof(snes_header_t));
|
||||
if(file_res) {
|
||||
score = 0;
|
||||
} else {
|
||||
score = smc_headerscore(header);
|
||||
}
|
||||
if(score>=maxscore) {
|
||||
score_idx=num;
|
||||
maxscore=score;
|
||||
}
|
||||
}
|
||||
|
||||
if(score_idx & 1) {
|
||||
props->offset = 0x200;
|
||||
} else {
|
||||
props->offset = 0;
|
||||
}
|
||||
|
||||
// restore the chosen one
|
||||
file_readblock(header, hdr_addr[score_idx], sizeof(snes_header_t));
|
||||
switch(header->map & 0xef) {
|
||||
case 0x20:
|
||||
props->mapper_id = 1;
|
||||
break;
|
||||
case 0x21:
|
||||
props->mapper_id = 0;
|
||||
break;
|
||||
case 0x25:
|
||||
props->mapper_id = 2;
|
||||
break;
|
||||
default:
|
||||
props->mapper_id = 0; // whatever
|
||||
}
|
||||
|
||||
props->ramsize_bytes = (uint32_t)1024 << header->ramsize;
|
||||
props->romsize_bytes = (uint32_t)1024 << header->romsize;
|
||||
props->expramsize_bytes = (uint32_t)1024 << header->expramsize;
|
||||
f_lseek(&file_handle, 0);
|
||||
}
|
||||
|
||||
uint8_t smc_headerscore(snes_header_t* header) {
|
||||
uint8_t score=0;
|
||||
score += countAllASCII(header->maker, sizeof(header->maker));
|
||||
score += countAllASCII(header->gamecode, sizeof(header->gamecode));
|
||||
score += isFixed(header->fixed_00, sizeof(header->fixed_00), 0x00);
|
||||
score += countAllJISX0201(header->name, sizeof(header->name));
|
||||
score += 3*isFixed(&header->fixed_33, sizeof(header->fixed_33), 0x33);
|
||||
score += checkChksum(header->cchk, header->chk);
|
||||
return score;
|
||||
}
|
||||
|
||||
46
src/smc.h
Normal file
46
src/smc.h
Normal file
@ -0,0 +1,46 @@
|
||||
// insert cool lengthy disclaimer here
|
||||
|
||||
/*
|
||||
* smc.h: data structures for SNES ROM images
|
||||
*/
|
||||
|
||||
#ifndef SMC_H
|
||||
#define SMC_H
|
||||
|
||||
typedef struct _snes_header {
|
||||
uint8_t maker[2]; // 0xB0
|
||||
uint8_t gamecode[4]; // 0xB2
|
||||
uint8_t fixed_00[7]; // 0xB6
|
||||
uint8_t expramsize; // 0xBD
|
||||
uint8_t specver; // 0xBE
|
||||
uint8_t carttype2; // 0xBF
|
||||
uint8_t name[21]; // 0xC0
|
||||
uint8_t map; // 0xD5
|
||||
uint8_t carttype; // 0xD6
|
||||
uint8_t romsize; // 0xD7
|
||||
uint8_t ramsize; // 0xD8
|
||||
uint8_t destcode; // 0xD9
|
||||
uint8_t fixed_33; // 0xDA
|
||||
uint8_t ver; // 0xDB
|
||||
uint16_t cchk; // 0xDC
|
||||
uint16_t chk; // 0xDE
|
||||
} snes_header_t;
|
||||
|
||||
typedef struct _snes_romprops {
|
||||
uint16_t offset; // start of actual ROM image
|
||||
uint8_t mapper_id; // FPGA mapper
|
||||
uint32_t expramsize_bytes; // ExpRAM size in bytes
|
||||
uint32_t ramsize_bytes; // CartRAM size in bytes
|
||||
uint32_t romsize_bytes; // ROM size in bytes (rounded up)
|
||||
snes_header_t header; // original header from ROM image
|
||||
} snes_romprops_t;
|
||||
|
||||
void smc_id(snes_romprops_t*);
|
||||
uint8_t smc_headerscore(snes_header_t*);
|
||||
|
||||
|
||||
/*pedef struct {
|
||||
|
||||
}*/
|
||||
|
||||
#endif
|
||||
@ -47,7 +47,7 @@ void snes_reset(int state) {
|
||||
void snes_main_loop() {
|
||||
if(initloop) {
|
||||
saveram_crc_old = calc_sram_crc(saveram_base_addr, saveram_size);
|
||||
save_sram("/test.srm", saveram_size, saveram_base_addr);
|
||||
save_sram("/quite a long test filename.srm", saveram_size, saveram_base_addr);
|
||||
initloop=0;
|
||||
}
|
||||
saveram_crc = calc_sram_crc(saveram_base_addr, saveram_size);
|
||||
@ -56,7 +56,7 @@ void snes_main_loop() {
|
||||
uart_puthexshort(saveram_crc);
|
||||
uart_putcrlf();
|
||||
set_busy_led(1);
|
||||
save_sram("/test.srm", saveram_size, saveram_base_addr);
|
||||
save_sram("/quite a long test filename.srm", saveram_size, saveram_base_addr);
|
||||
set_busy_led(0);
|
||||
}
|
||||
saveram_crc_old = saveram_crc;
|
||||
|
||||
@ -56,15 +56,16 @@ end
|
||||
Index Mapper
|
||||
000 HiROM
|
||||
001 LoROM
|
||||
010 ExHiROM
|
||||
010 ExHiROM (48-64Mbit)
|
||||
*/
|
||||
|
||||
/* HiROM: SRAM @ Bank 0x20-0x3f, 0xa0-0xbf
|
||||
/* HiROM: SRAM @ Bank 0x30-0x3f, 0xb0-0xbf
|
||||
Offset 6000-7fff */
|
||||
assign IS_SAVERAM = ((MAPPER == 3'b000 || MAPPER == 3'b010) ? (!SNES_ADDR[22]
|
||||
& SNES_ADDR[21]
|
||||
& SNES_ADDR[21:20]
|
||||
& &SNES_ADDR[14:13]
|
||||
& !SNES_ADDR[15]
|
||||
& SNES_CS
|
||||
)
|
||||
/* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd
|
||||
Offset 0000-7fff TODO: 0000-ffff for
|
||||
|
||||
@ -182,3 +182,52 @@ NET "SRAM_DATA[8]" LOC = P96;
|
||||
NET "SRAM_DATA[9]" LOC = P98;
|
||||
NET "SRAM_OE" LOC = P93;
|
||||
NET "CLKIN" IOSTANDARD = LVCMOS33;
|
||||
TIMESPEC TS_test = FROM "FFS" TO "FFS" 10 ns;
|
||||
NET "SNES_ADDR<0>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<0>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<1>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<1>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<2>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<2>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<3>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<3>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<4>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<4>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<5>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<5>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<6>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<6>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<7>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<7>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<8>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<8>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<9>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<9>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<10>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<10>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<11>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<11>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<12>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<12>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<13>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<13>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<14>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<14>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<15>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<15>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<16>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<16>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<17>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<17>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<18>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<18>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<19>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<19>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<20>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<20>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<21>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<21>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<22>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<22>" MAXSKEW = 5 ns;
|
||||
NET "SNES_ADDR<23>" MAXDELAY = 10 ns;
|
||||
NET "SNES_ADDR<23>" MAXSKEW = 5 ns;
|
||||
|
||||
@ -120,14 +120,20 @@ wire SNES_RW;
|
||||
reg [1:0] SNES_READr;
|
||||
reg [1:0] SNES_WRITEr;
|
||||
reg [1:0] SNES_CSr;
|
||||
reg [1:0] SNES_CPU_CLKr;
|
||||
reg [7:0] SNES_RWr;
|
||||
reg [5:0] SNES_CPU_CLKr;
|
||||
reg [5:0] SNES_RWr;
|
||||
reg [23:0] SNES_ADDRr;
|
||||
reg [23:0] SNES_ADDR_PREVr;
|
||||
reg [3:0] SNES_ADDRCHGr;
|
||||
|
||||
wire SNES_READs = (SNES_READr == 2'b11);
|
||||
wire SNES_WRITEs = (SNES_WRITEr == 2'b11);
|
||||
wire SNES_CSs = (SNES_CSr == 2'b11);
|
||||
wire SNES_CPU_CLKs = SNES_CPU_CLK; // (SNES_CPU_CLKr == 2'b11);
|
||||
wire SNES_RW_start = (SNES_RWr == 8'b11111110); // falling edge marks beginning of cycle
|
||||
wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle
|
||||
wire SNES_cycle_start = (SNES_CPU_CLKr == 6'b000001);
|
||||
wire SNES_ADDRCHG = (SNES_ADDRr != SNES_ADDR_PREVr);
|
||||
wire SNES_addr_start = (SNES_ADDRCHGr[0] == 1'b1);
|
||||
|
||||
assign SNES_RW = (SNES_READ & SNES_WRITE);
|
||||
|
||||
@ -135,11 +141,15 @@ always @(posedge CLK2) begin
|
||||
SNES_READr <= {SNES_READr[0], SNES_READ};
|
||||
SNES_WRITEr <= {SNES_WRITEr[0], SNES_WRITE};
|
||||
SNES_CSr <= {SNES_CSr[0], SNES_CS};
|
||||
SNES_CPU_CLKr <= {SNES_CPU_CLKr[0], SNES_CPU_CLK};
|
||||
SNES_RWr <= {SNES_RWr[6:0], SNES_RW};
|
||||
SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK};
|
||||
SNES_RWr <= {SNES_RWr[4:0], SNES_RW};
|
||||
end
|
||||
|
||||
reg ADDR_WRITE;
|
||||
|
||||
//reg [23:0] SNES_ADDRr;
|
||||
//wire [23:0] SNES_ADDRw = SNES_ADDR;
|
||||
|
||||
|
||||
address snes_addr(
|
||||
.CLK(CLK2),
|
||||
@ -157,6 +167,11 @@ address snes_addr(
|
||||
.SAVERAM_MASK(SAVERAM_MASK),
|
||||
.ROM_MASK(ROM_MASK)
|
||||
);
|
||||
|
||||
wire SNES_READ_CYCLEw;
|
||||
wire SNES_WRITE_CYCLEw;
|
||||
wire AVR_READ_CYCLEw;
|
||||
wire AVR_WRITE_CYCLEw;
|
||||
|
||||
data snes_data(.CLK(CLK2),
|
||||
.SNES_READ(SNES_READ),
|
||||
@ -179,33 +194,36 @@ data snes_data(.CLK(CLK2),
|
||||
parameter MODE_SNES = 1'b0;
|
||||
parameter MODE_AVR = 1'b1;
|
||||
|
||||
parameter STATE_0 = 10'b0000000001;
|
||||
parameter STATE_1 = 10'b0000000010;
|
||||
parameter STATE_2 = 10'b0000000100;
|
||||
parameter STATE_3 = 10'b0000001000;
|
||||
parameter STATE_4 = 10'b0000010000;
|
||||
parameter STATE_5 = 10'b0000100000;
|
||||
parameter STATE_6 = 10'b0001000000;
|
||||
parameter STATE_7 = 10'b0010000000;
|
||||
parameter STATE_8 = 10'b0100000000;
|
||||
parameter STATE_9 = 10'b1000000000;
|
||||
parameter STATE_0 = 13'b0000000000001;
|
||||
parameter STATE_1 = 13'b0000000000010;
|
||||
parameter STATE_2 = 13'b0000000000100;
|
||||
parameter STATE_3 = 13'b0000000001000;
|
||||
parameter STATE_4 = 13'b0000000010000;
|
||||
parameter STATE_5 = 13'b0000000100000;
|
||||
parameter STATE_6 = 13'b0000001000000;
|
||||
parameter STATE_7 = 13'b0000010000000;
|
||||
parameter STATE_8 = 13'b0000100000000;
|
||||
parameter STATE_9 = 13'b0001000000000;
|
||||
parameter STATE_10 = 13'b0010000000000;
|
||||
parameter STATE_11 = 13'b0100000000000;
|
||||
parameter STATE_IDLE = 13'b1000000000000;
|
||||
|
||||
reg [9:0] STATE;
|
||||
reg [12:0] STATE;
|
||||
reg [3:0] STATEIDX;
|
||||
|
||||
reg STATE_RESET, CYCLE_RESET, CYCLE_RESET_ACK;
|
||||
reg [1:0] CYCLE_RESET;
|
||||
reg SRAM_WE_MASK;
|
||||
reg SRAM_OE_MASK;
|
||||
|
||||
reg [9:0] SRAM_WE_ARRAY [3:0];
|
||||
reg [9:0] SRAM_OE_ARRAY [3:0];
|
||||
reg [12:0] SRAM_WE_ARRAY [3:0];
|
||||
reg [12:0] SRAM_OE_ARRAY [3:0];
|
||||
|
||||
reg [9:0] SNES_DATA_TO_MEM_ARRAY[1:0];
|
||||
reg [9:0] AVR_DATA_TO_MEM_ARRAY[1:0];
|
||||
reg [9:0] SRAM_DATA_TO_SNES_MEM_ARRAY[1:0];
|
||||
reg [9:0] SRAM_DATA_TO_AVR_MEM_ARRAY[1:0];
|
||||
reg [12:0] SNES_DATA_TO_MEM_ARRAY[1:0];
|
||||
reg [12:0] AVR_DATA_TO_MEM_ARRAY[1:0];
|
||||
reg [12:0] SRAM_DATA_TO_SNES_MEM_ARRAY[1:0];
|
||||
reg [12:0] SRAM_DATA_TO_AVR_MEM_ARRAY[1:0];
|
||||
|
||||
reg [9:0] MODE_ARRAY;
|
||||
reg [12:0] MODE_ARRAY;
|
||||
|
||||
reg SNES_READ_CYCLE;
|
||||
reg SNES_WRITE_CYCLE;
|
||||
@ -225,41 +243,39 @@ reg SNES_DATABUS_DIR_BUF;
|
||||
assign MODE = !AVR_ENA ? MODE_AVR : MODE_ARRAY[STATEIDX];
|
||||
|
||||
initial begin
|
||||
CYCLE_RESET = 0;
|
||||
CYCLE_RESET_ACK = 0;
|
||||
CYCLE_RESET = 2'b0;
|
||||
|
||||
STATE = STATE_9;
|
||||
STATEIDX = 9;
|
||||
STATE = STATE_IDLE;
|
||||
STATEIDX = 12;
|
||||
SRAM_WE_MASK = 1'b1;
|
||||
SRAM_OE_MASK = 1'b1;
|
||||
SNES_READ_CYCLE = 1'b1;
|
||||
SNES_WRITE_CYCLE = 1'b1;
|
||||
AVR_READ_CYCLE = 1'b1;
|
||||
AVR_WRITE_CYCLE = 1'b1;
|
||||
MODE_ARRAY = 13'b0000000111111;
|
||||
|
||||
SRAM_WE_ARRAY[2'b00] = 13'b1000000000000;
|
||||
SRAM_WE_ARRAY[2'b01] = 13'b1000000111111;
|
||||
SRAM_WE_ARRAY[2'b10] = 13'b1111111000000;
|
||||
SRAM_WE_ARRAY[2'b11] = 13'b1111111111111;
|
||||
|
||||
MODE_ARRAY = 10'b0000011111;
|
||||
SRAM_OE_ARRAY[2'b00] = 13'b1111111111111;
|
||||
SRAM_OE_ARRAY[2'b01] = 13'b1111111000000;
|
||||
SRAM_OE_ARRAY[2'b10] = 13'b0000000111111;
|
||||
SRAM_OE_ARRAY[2'b11] = 13'b0000000000000;
|
||||
|
||||
SRAM_WE_ARRAY[2'b00] = 10'b1000010000;
|
||||
SRAM_WE_ARRAY[2'b01] = 10'b1000011111;
|
||||
SRAM_WE_ARRAY[2'b10] = 10'b1111110000;
|
||||
SRAM_WE_ARRAY[2'b11] = 10'b1111111111;
|
||||
|
||||
SRAM_OE_ARRAY[2'b00] = 10'b1111111111;
|
||||
SRAM_OE_ARRAY[2'b01] = 10'b1111100000;
|
||||
SRAM_OE_ARRAY[2'b10] = 10'b0000011111;
|
||||
SRAM_OE_ARRAY[2'b11] = 10'b0000000000;
|
||||
SNES_DATA_TO_MEM_ARRAY[1'b0] = 13'b0001000000000; // SNES write
|
||||
SNES_DATA_TO_MEM_ARRAY[1'b1] = 13'b0000000000000; // SNES read
|
||||
|
||||
SNES_DATA_TO_MEM_ARRAY[1'b0] = 10'b1000000000;
|
||||
SNES_DATA_TO_MEM_ARRAY[1'b1] = 10'b0000000000;
|
||||
AVR_DATA_TO_MEM_ARRAY[1'b0] = 13'b0000000010000; // AVR write
|
||||
AVR_DATA_TO_MEM_ARRAY[1'b1] = 13'b0000000000000; // AVR read
|
||||
|
||||
AVR_DATA_TO_MEM_ARRAY[1'b0] = 10'b0000010000;
|
||||
AVR_DATA_TO_MEM_ARRAY[1'b1] = 10'b0000000000;
|
||||
SRAM_DATA_TO_SNES_MEM_ARRAY[1'b0] = 13'b0000000000000; // SNES write
|
||||
SRAM_DATA_TO_SNES_MEM_ARRAY[1'b1] = 13'b0000100000000; // SNES read
|
||||
|
||||
SRAM_DATA_TO_SNES_MEM_ARRAY[1'b0] = 10'b0000000000;
|
||||
SRAM_DATA_TO_SNES_MEM_ARRAY[1'b1] = 10'b0000100000;
|
||||
|
||||
SRAM_DATA_TO_AVR_MEM_ARRAY[1'b0] = 10'b0000000000;
|
||||
SRAM_DATA_TO_AVR_MEM_ARRAY[1'b1] = 10'b0000000001;
|
||||
SRAM_DATA_TO_AVR_MEM_ARRAY[1'b0] = 13'b0000000000000; // AVR write
|
||||
SRAM_DATA_TO_AVR_MEM_ARRAY[1'b1] = 13'b0000000000001; // AVR read
|
||||
end
|
||||
|
||||
// falling edge of SNES /RD or /WR marks the beginning of a new cycle
|
||||
@ -268,48 +284,66 @@ end
|
||||
// the minimum of 6 SNES cycles to get everything done.
|
||||
// we have 24 internal cycles to work with. (CLKIN * 4)
|
||||
|
||||
reg [1:0] CYCLE_RESET;
|
||||
|
||||
always @(posedge CLK2) begin
|
||||
CYCLE_RESET <= {CYCLE_RESET[0], SNES_RW_start};
|
||||
CYCLE_RESET <= {CYCLE_RESET[0], SNES_cycle_start};
|
||||
end
|
||||
|
||||
always @(posedge CLK2) begin
|
||||
if (CYCLE_RESET[1]) begin
|
||||
STATE <= STATE_0;
|
||||
if (SNES_RW_start) begin
|
||||
SNES_READ_CYCLE <= SNES_READ;
|
||||
SNES_WRITE_CYCLE <= SNES_WRITE;
|
||||
AVR_READ_CYCLE <= AVR_READ;
|
||||
AVR_WRITE_CYCLE <= AVR_WRITE;
|
||||
STATE <= STATE_0;
|
||||
STATEIDX <= 11;
|
||||
end else begin
|
||||
case (STATE)
|
||||
STATE_0:
|
||||
STATE <= STATE_1;
|
||||
STATE_1:
|
||||
STATE <= STATE_2;
|
||||
STATE_2:
|
||||
STATE <= STATE_3;
|
||||
STATE_3:
|
||||
STATE <= STATE_4;
|
||||
STATE_4:
|
||||
STATE <= STATE_5;
|
||||
STATE_5:
|
||||
STATE <= STATE_6;
|
||||
STATE_6:
|
||||
STATE <= STATE_7;
|
||||
STATE_7:
|
||||
STATE <= STATE_8;
|
||||
STATE_8:
|
||||
STATE <= STATE_9;
|
||||
STATE_0: begin
|
||||
STATE <= STATE_1; STATEIDX <= 10;
|
||||
end
|
||||
STATE_1: begin
|
||||
STATE <= STATE_2; STATEIDX <= 9;
|
||||
end
|
||||
STATE_2: begin
|
||||
STATE <= STATE_3; STATEIDX <= 8;
|
||||
end
|
||||
STATE_3: begin
|
||||
STATE <= STATE_4; STATEIDX <= 7;
|
||||
end
|
||||
STATE_4: begin
|
||||
STATE <= STATE_5; STATEIDX <= 6;
|
||||
end
|
||||
STATE_5: begin
|
||||
STATE <= STATE_6; STATEIDX <= 5;
|
||||
end
|
||||
STATE_6: begin
|
||||
STATE <= STATE_7; STATEIDX <= 4;
|
||||
end
|
||||
STATE_7: begin
|
||||
STATE <= STATE_8; STATEIDX <= 3;
|
||||
end
|
||||
STATE_8: begin
|
||||
STATE <= STATE_9; STATEIDX <= 2;
|
||||
end
|
||||
STATE_9: begin
|
||||
STATE <= STATE_9;
|
||||
end
|
||||
default:
|
||||
STATE <= STATE_9;
|
||||
STATE <= STATE_10; STATEIDX <= 1;
|
||||
end
|
||||
STATE_10: begin
|
||||
STATE <= STATE_11; STATEIDX <= 0;
|
||||
end
|
||||
STATE_11: begin
|
||||
STATE <= STATE_IDLE; STATEIDX <= 12;
|
||||
end
|
||||
STATE_IDLE: begin
|
||||
STATE <= STATE_IDLE; STATEIDX <= 12;
|
||||
end
|
||||
default: begin
|
||||
STATE <= STATE_IDLE; STATEIDX <= 12;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
always @(posedge CLK2) begin
|
||||
|
||||
case (STATE)
|
||||
@ -356,7 +390,7 @@ always @(posedge CLK2) begin
|
||||
STATEIDX <= 9;
|
||||
endcase
|
||||
end
|
||||
|
||||
*/
|
||||
// When in AVR mode, enable SRAM_WE according to AVR programming
|
||||
// else enable SRAM_WE according to state&cycle
|
||||
assign SRAM_WE = !AVR_ENA ? AVR_WRITE
|
||||
@ -375,8 +409,8 @@ assign SRAM_BLE = !SRAM_WE ? !SRAM_ADDR0 : 1'b0;
|
||||
//assign SRAM_WE = !AVR_ENA ? AVR_WRITE : 1'b1;
|
||||
|
||||
//assign SNES_DATABUS_OE = (!IS_SAVERAM & SNES_CS) | (SNES_READ & SNES_WRITE);
|
||||
assign SNES_DATABUS_OE = (IS_ROM & SNES_CSs) | (!IS_ROM & !IS_SAVERAM) | (SNES_READs & SNES_WRITEs);
|
||||
assign SNES_DATABUS_DIR = !SNES_WRITEs ? 1'b0 : 1'b1;
|
||||
assign SNES_DATABUS_OE = (IS_ROM & SNES_CS) | (!IS_ROM & !IS_SAVERAM) | (SNES_READ & SNES_WRITE);
|
||||
assign SNES_DATABUS_DIR = !SNES_READ ? 1'b1 : 1'b0;
|
||||
|
||||
assign SNES_DATA_TO_MEM = SNES_DATA_TO_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX];
|
||||
assign AVR_DATA_TO_MEM = AVR_DATA_TO_MEM_ARRAY[AVR_WRITE_CYCLE][STATEIDX];
|
||||
@ -384,6 +418,8 @@ assign AVR_DATA_TO_MEM = AVR_DATA_TO_MEM_ARRAY[AVR_WRITE_CYCLE][STATEIDX];
|
||||
assign SRAM_DATA_TO_SNES_MEM = SRAM_DATA_TO_SNES_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX];
|
||||
assign SRAM_DATA_TO_AVR_MEM = SRAM_DATA_TO_AVR_MEM_ARRAY[AVR_WRITE_CYCLE][STATEIDX];
|
||||
|
||||
assign SNES_READ_CYCLEw = SNES_READ_CYCLE;
|
||||
assign SNES_WRITE_CYCLEw = SNES_WRITE_CYCLE;
|
||||
assign IRQ_DIR = 1'b0;
|
||||
assign SNES_IRQ = 1'bZ;
|
||||
|
||||
|
||||
@ -69,21 +69,30 @@
|
||||
|
||||
<properties>
|
||||
<property xil_pn:name="Auto Implementation Top" xil_pn:value="false"/>
|
||||
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="true"/>
|
||||
<property xil_pn:name="Constraints Entry" xil_pn:value="Constraints Editor"/>
|
||||
<property xil_pn:name="Device" xil_pn:value="xc3s200"/>
|
||||
<property xil_pn:name="Device Family" xil_pn:value="Spartan3"/>
|
||||
<property xil_pn:name="Extra Effort" xil_pn:value="Normal"/>
|
||||
<property xil_pn:name="Extra Effort (Highest PAR level only)" xil_pn:value="Normal"/>
|
||||
<property xil_pn:name="Fitter Report Format" xil_pn:value="HTML"/>
|
||||
<property xil_pn:name="Generate Asynchronous Delay Report" xil_pn:value="true"/>
|
||||
<property xil_pn:name="Generate Detailed MAP Report" xil_pn:value="true"/>
|
||||
<property xil_pn:name="Implementation Top" xil_pn:value="Module|main"/>
|
||||
<property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/main"/>
|
||||
<property xil_pn:name="Map Effort Level" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Map Slice Logic into Unused Block RAMs" xil_pn:value="true"/>
|
||||
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Speed"/>
|
||||
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="PROP_DesignName" xil_pn:value="sd2snes"/>
|
||||
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="Package" xil_pn:value="tq144"/>
|
||||
<property xil_pn:name="Perform Timing-Driven Packing" xil_pn:value="true"/>
|
||||
<property xil_pn:name="Place & Route Effort Level (Overall)" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Placer Effort Level (Overrides Overall Level)" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Preferred Language" xil_pn:value="Verilog"/>
|
||||
<property xil_pn:name="Project Description" xil_pn:value="sd2snes"/>
|
||||
<property xil_pn:name="Register Duplication" xil_pn:value="On"/>
|
||||
<property xil_pn:name="Router Effort Level (Overrides Overall Level)" xil_pn:value="High"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="Module|main_tf2"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="Module|main_tf2"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user