Beispiel #1
1
int load_wav (
FIL *fp,			/* Pointer to the open file object to play */
const char *title,	/* Title (file name, etc...) */
void *work,			/* Pointer to working buffer (must be-4 byte aligned) */
UINT sz_work		/* Size of working buffer (must be power of 2) */
)
{
	UINT md, wi, br, tc, t, btr;
	DWORD sz, ssz, offw, szwav, wsmp, fsmp, eof;
	WAVFIFO fcb;
	BYTE k, *buff = work;
	char *p, nam[NBSIZE], art[NBSIZE];


	//xprintf(PSTR("%s\n"), title);	/* Put title */

	/* Is it a WAV file? */
	if (f_read(fp, buff, 12, &br) || br != 12) return -1;
	if (LD_DWORD(&buff[0]) != FCC('R','I','F','F')) return -1;
	if (LD_DWORD(&buff[8]) != FCC('W','A','V','E')) return -1;
	eof = LD_DWORD(&buff[4]) + 8;

	/* Analyze the RIFF-WAVE header and get properties */
	nam[0] = art[0] = 0;
	md = fsmp = wsmp = offw = szwav = 0;
	while (f_tell(fp) < eof) {
		if (f_read(fp, buff, 8, &br) || br != 8) return -1;
		sz = (LD_DWORD(&buff[4]) + 1) & ~1;
		switch (LD_DWORD(&buff[0])) {
			case FCC('f','m','t',' ') :
			if (sz > 1000 || sz < 16 || f_read(fp, buff, sz, &br) || sz != br) return -1;
			if (LD_WORD(&buff[0]) != 0x1) return -1;	/* Check if LPCM */
			if (LD_WORD(&buff[2]) == 2) {	/* Channels (1 or 2) */
				md = 1; wsmp = 2;
				} else {
				md = 0; wsmp = 1;
			}
			if (LD_WORD(&buff[14]) == 16) {	/* Resolution (8 or 16) */
				md |= 2; wsmp *= 2;
			}
			fsmp = LD_DWORD(&buff[4]);		/* Sampling rate */
			break;

			case FCC('f','a','c','t') :
			f_lseek(fp, f_tell(fp) + sz);
			break;

			case FCC('d','a','t','a') :
			offw = f_tell(fp);	/* Wave data start offset */
			szwav = sz;			/* Wave data length [byte] */
			f_lseek(fp, f_tell(fp) + sz);
			break;

			case FCC('L','I','S','T'):
			sz += f_tell(fp);
			if (f_read(fp, buff, 4, &br) || br != 4) return -1;
			if (LD_DWORD(buff) == FCC('I','N','F','O')) {	/* LIST/INFO chunk */
				while (f_tell(fp) < sz) {
					if (f_read(fp, buff, 8, &br) || br != 8) return -1;
					ssz = (LD_DWORD(&buff[4]) + 1) & ~1;
					p = 0;
					switch (LD_DWORD(buff)) {
						case FCC('I','N','A','M'):		/* INAM sub-chunk */
						p = nam; break;
						case FCC('I','A','R','T'):		/* IART sub-cnunk */
						p = art; break;
					}
					if (p && ssz <= NBSIZE) {
						if (f_read(fp, p, ssz, &br) || br != ssz) return -1;
						} else {
						if (f_lseek(fp, f_tell(fp) + ssz)) return -1;
					}
				}
				} else {
				if (f_lseek(fp, sz)) return -1;	/* Skip unknown sub-chunk type */
			}
			break;

			default :	/* Unknown chunk */
			return -1;
		}
	}
	if (!szwav || !fsmp) return -1;		/* Check if valid WAV file */
	if (f_lseek(fp, offw)) return -1;	/* Seek to top of wav data */
	tc = (UINT)(szwav / fsmp / wsmp);	/* Length (sec) */

	//xprintf(PSTR("IART=%s\nINAM=%s\n"), art, nam);
	//xprintf(PSTR("Sample=%u.%ukHz/%ubit/%S\nLength=%u:%02u\n"), (UINT)(fsmp / 1000), (UINT)(fsmp / 100) % 10, (md & 2) ? 16 : 8, (md & 1) ? PSTR("st") : PSTR("mo"), tc / 60, tc % 60);

	/* Initialize stream parameters and start sound streming */
	fcb.mode = md;
	fcb.buff = buff;
	fcb.sz_buff = sz_work;
	if (!sound_start(&fcb, fsmp)) return -1;

	k = 0; wi = 0;
	while (szwav || fcb.ct >= 4) {
		if (szwav && fcb.ct <= sz_work / 2) {	/* Refill FIFO when it gets half empty */
			btr = (szwav >= sz_work / 2) ? sz_work / 2 : szwav;
			f_read(fp, &buff[wi], btr, &br);
			if (br != btr) break;
			szwav -= br;
			wi = (wi + br) & (sz_work - 1);
			cli();
			fcb.ct += br;
			sei();
		}
		//if (uart_test()) {		/* Exit if a command arrived */
		//	k = uart_getc();
		//	break;
		//}
		
		if (btn_check_press() == BTN2)
		{
			sound_stop();
			break;
		}
		
		t = (f_tell(fp) - offw - fcb.ct) / fsmp / wsmp;	/* Refresh time display every 1 sec */
		if (t != tc) {
			tc = t;
			//xprintf(PSTR("\rTime=%u:%02u"), tc / 60, tc % 60);
		}
	}

	sound_stop();	/* Stop sound output */

	//xputc('\n');
	return k;	/* Terminated due to -1:error, 0:eot, >0:key code */
}
Beispiel #2
0
static
DWORD load_header (void)	/* 0:Invalid format, 1:I/O error, >=1024:Number of samples */
{
	DWORD sz, f;
	BYTE b, al = 0;


	if (pf_read(Buff, 12, &rb)) return 1;	/* Load file header (12 bytes) */

	if (rb != 12 || LD_DWORD(Buff+8) != FCC('W','A','V','E')) return 0;

	for (;;) {
		wdt_reset();
		pf_read(Buff, 8, &rb);			/* Get Chunk ID and size */
		if (rb != 8) return 0;
		sz = LD_DWORD(&Buff[4]);		/* Chunk size */

		switch (LD_DWORD(&Buff[0])) {	/* Switch by chunk ID */
		case FCC('f','m','t',' ') :					/* 'fmt ' chunk */
			if (sz & 1) sz++;						/* Align chunk size */
			if (sz > 100 || sz < 16) return 0;		/* Check chunk size */
			pf_read(Buff, sz, &rb);					/* Get content */
			if (rb != sz) return 0;
			if (Buff[0] != 1) return 0;				/* Check coding type (LPCM) */
			b = Buff[2];
			if (b != 1 && b != 2) return 0;			/* Check channels (1/2) */
			GPIOR0 = al = b;						/* Save channel flag */
			b = Buff[14];
			if (b != 8 && b != 16) return 0;		/* Check resolution (8/16 bit) */
			GPIOR0 |= b;							/* Save resolution flag */
			if (b & 16) al <<= 1;
			f = LD_DWORD(&Buff[4]);					/* Check sampling freqency (8k-48k) */
			if (f < 8000 || f > 48000) return 4;
			OCR0A = (BYTE)(F_CPU / 8 / f) - 1;		/* Set sampling interval */
			break;

		case FCC('d','a','t','a') :		/* 'data' chunk */
			if (!al) return 0;							/* Check if format is valid */
			if (sz < 1024 || (sz & (al - 1))) return 0;	/* Check size */
			if (Fs.fptr & (al - 1)) return 0;			/* Check word alignment */
			return sz;									/* Start to play */

		case FCC('D','I','S','P') :		/* 'DISP' chunk */
		case FCC('L','I','S','T') :		/* 'LIST' chunk */
		case FCC('f','a','c','t') :		/* 'fact' chunk */
			if (sz & 1) sz++;				/* Align chunk size */
			pf_lseek(Fs.fptr + sz);			/* Skip this chunk */
			break;

		default :						/* Unknown chunk */
			return 0;
		}
	}

	return 0;
}
Beispiel #3
0
static
DWORD loadheader (FIL* fp)	/* 0:Invalid format, 1:I/O error, >=1024:Number of samples */
{
	DWORD sz, f;
	BYTE b;
	UINT rb;

	if (f_read(fp, buffer, 12, &rb) != FR_OK) return 1;	/* Load file header (12 bytes) */

	if (rb != 12 || LD_DWORD(buffer+8) != FCC('W','A','V','E')) return 0;

	for (;;) {
		f_read(fp, buffer, 8, &rb);				/* Get Chunk ID and size */
		if (rb != 8) return 0;
		sz = LD_DWORD(&buffer[4]);					/* Chunk size */

		switch (LD_DWORD(&buffer[0])) {			/* Switch by chunk ID */
		case FCC('f','m','t',' ') :					/* 'fmt ' chunk */
			if (sz & 1) sz++;						/* Align chunk size */
			if (sz > 100 || sz < 16) return 0;		/* Check chunk size */
			f_read(fp, buffer, sz, &rb);			/* Get content */
			if (rb != sz) return 0;
			if (buffer[0] != 1) return 0;			/* Check coding type (LPCM) */
			b = buffer[2];
			if (b != 1) return 0;					/* Mono Only */
			b = buffer[14];
			if (b != 8) return 0;					/* resolution 8bit only */
			f = LD_DWORD(&buffer[4]);				/* Check sampling freqency (8k-48k) */
			if (f != 8000) return 4;				/* 8kHz only */
			break;

		case FCC('d','a','t','a') :				/* 'data' chunk */
			if (sz < 1024) return 0;				/* Check size */
			return sz;								/* Start to play */

		case FCC('D','I','S','P') :				/* 'DISP' chunk */
		case FCC('L','I','S','T') :				/* 'LIST' chunk */
		case FCC('f','a','c','t') :				/* 'fact' chunk */
			if (sz & 1) sz++;						/* Align chunk size */
			f_lseek(fp, fp->fptr + sz);				/* Skip this chunk */
			break;

		default :								/* Unknown chunk */
			return 0;
		}
	}

	return 0;
}
Beispiel #4
0
FRESULT pf_open (
	const char *path	/* Pointer to the file name */
)
{
	FRESULT res;
	DIR dj;
	BYTE sp[12], dir[32];
	FATFS *fs = FatFs;


	if (!fs) return FR_NOT_ENABLED;		/* Check file system */

	fs->flag = 0;
	dj.fn = sp;
	res = follow_path(&dj, dir, path);	/* Follow the file path */
	if (res != FR_OK) return res;		/* Follow failed */
	if (!dir[0] || (dir[DIR_Attr] & AM_DIR))	/* It is a directory */
		return FR_NO_FILE;

	fs->org_clust = get_clust(dir);		/* File start cluster */
	fs->fsize = LD_DWORD(dir+DIR_FileSize);	/* File size */
	fs->fptr = 0;						/* File pointer */
	fs->flag = FA_OPENED;

	return FR_OK;
}
Beispiel #5
0
static
void get_fileinfo (		/* No return code */
	DIR *dj,			/* Pointer to the directory object */
	BYTE *dir,			/* 32-byte working buffer */
	FILINFO *fno	 	/* Pointer to store the file information */
)
{
	BYTE i, c;
	char *p;


	p = fno->fname;
	if (dj->sect) {
		for (i = 0; i < 8; i++) {	/* Copy file name body */
			c = dir[i];
			if (c == ' ') break;
			if (c == 0x05) c = 0xE5;
			*p++ = c;
		}
		if (dir[8] != ' ') {		/* Copy file name extension */
			*p++ = '.';
			for (i = 8; i < 11; i++) {
				c = dir[i];
				if (c == ' ') break;
				*p++ = c;
			}
		}
		fno->fattrib = dir[DIR_Attr];				/* Attribute */
		fno->fsize = LD_DWORD(dir+DIR_FileSize);	/* Size */
		fno->fdate = LD_WORD(dir+DIR_WrtDate);		/* Date */
		fno->ftime = LD_WORD(dir+DIR_WrtTime);		/* Time */
	}
	*p = 0;
}
Beispiel #6
0
FRESULT pf_open (
	const char *path	/* Pointer to the file name */
)
{
	FRESULT res;
	DIR dj;
	BYTE sp[12], dir[32];
	FATFS *fs = FatFs;


	if (!fs)						/* Check file system */
		return FR_NOT_ENABLED;

	fs->flag = 0;
	fs->buf = dir;
	dj.fn = sp;
	res = follow_path(&dj, path);	/* Follow the file path */
	if (res != FR_OK) return res;	/* Follow failed */
	if (!dir[0] || (dir[DIR_Attr] & AM_DIR))	/* It is a directory */
		return FR_NO_FILE;

	fs->org_clust =						/* File start cluster */
#if _FS_FAT32
		((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
#endif
		LD_WORD(dir+DIR_FstClusLO);
	fs->fsize = LD_DWORD(dir+DIR_FileSize);	/* File size */
	fs->fptr = 0;						/* File pointer */
	fs->flag = FA_READ;

	return FR_OK;
}
Beispiel #7
0
static
CLUST get_cluster (		/* 0,>=2: successful, 1: failed */
	CLUST clust			/* Cluster# to get the link information */
)
{
   WORD wc, bc;
   DWORD fatsect;
  FATFS *fs = FatFs;


	if (clust >= 2 && clust < fs->max_clust) {		/* Valid cluster# */
		fatsect = fs->fatbase;
		switch (fs->fs_type) {
		case FS_FAT12 :
			bc = (WORD)clust * 3 / 2;
			if (!move_window(fatsect + bc / 512)) break;
			wc = fs->win[bc % 512]; bc++;
			if (!move_window(fatsect + bc / 512)) break;
			wc |= (WORD)fs->win[bc % 512] << 8;
			return (clust & 1) ? (wc >> 4) : (wc & 0xFFF);

		case FS_FAT16 :
			if (!move_window(fatsect + clust / 256)) break;
			return LD_WORD(&fs->win[((WORD)clust * 2) % 512]);
#if _FAT32
		case FS_FAT32 :
			if (!move_window(fatsect + clust / 128)) break;
			return LD_DWORD(&fs->win[((WORD)clust * 4) % 512]) & 0x0FFFFFFF;
#endif
		}
	}
Beispiel #8
0
Datei: ff.c Projekt: optixx/lm32
static
DWORD get_cluster (
	DWORD clust			/* Cluster# to get the link information */
)
{
	WORD wc, bc;
	DWORD fatsect;
	FATFS *fs = FatFs;


	if ((clust >= 2) && (clust < fs->max_clust)) {		/* Valid cluster# */
		fatsect = fs->fatbase;
		switch (fs->fs_type) {
		case FS_FAT12 :
			bc = (WORD)clust * 3 / 2;
			if (!move_window(fatsect + bc / 512)) break;
			wc = fs->win[bc % 512]; bc++;
			if (!move_window(fatsect + bc / 512)) break;
			wc |= (WORD)fs->win[bc % 512] << 8;
			return (clust & 1) ? (wc >> 4) : (wc & 0xFFF);

		case FS_FAT16 :
			if (!move_window(fatsect + clust / 256)) break;
			return LD_WORD(&(fs->win[((WORD)clust * 2) % 512]));

		case FS_FAT32 :
			if (!move_window(fatsect + clust / 128)) break;
			return LD_DWORD(&(fs->win[((WORD)clust * 4) % 512]));
		}
	}
Beispiel #9
0
static
DWORD load_header (void)	/* 0:Invalid format, 1:I/O error, >1:Number of samples */
{
	DWORD sz;


	if (pf_read(Buff1, 12, &rb)) return 1;	/* Load file header (12 bytes) */

	if (rb != 12 || LD_DWORD(Buff1+8) != FCC('W','A','V','E')) return 0;

	for (;;) {
		pf_read(Buff1, 8, &rb);			/* Get Chunk ID and size */
		if (rb != 8) return 0;
		sz = LD_DWORD(&Buff1[4]);		/* Chunk size */

		switch (LD_DWORD(&Buff1[0])) {	/* FCC */
		case FCC('f','m','t',' ') :					/* 'fmt ' chunk */
			if (sz > 100 || sz < 16) return 0;		/* Check chunk size */
			pf_read(Buff1, sz, &rb);					/* Get content */
			if (rb != sz) return 0;
			if (Buff1[0] != 1) return 0;				/* Check coding type (1) */
			if (Buff1[2] != 1 && Buff1[2] != 2) 		/* Check channels (1/2) */
				return 0;
			
			if (Buff1[14] != 8 && Buff1[14] != 16)	/* Check resolution (8/16) */
				return 0;
			
			OCR0A = (BYTE)(F_CPU/8/LD_WORD(&Buff1[4]))-1;	/* Sampling freq */
			
			break;

		case FCC('d','a','t','a') :				/* 'data' chunk (start to play) */
			return sz;

		case FCC('L','I','S','T') :				/* 'LIST' chunk (skip) */
		case FCC('f','a','c','t') :				/* 'fact' chunk (skip) */
			pf_lseek(Fs.fptr + sz);
			break;

		default :								/* Unknown chunk (error) */
			return 0;
		}
	}

	return 0;
}
Beispiel #10
0
static
CLUST get_fat (	/* 1:IO error, Else:Cluster status */
    CLUST clst	/* Cluster# to get the link information */
)
{
    BYTE buf[4];
    FATFS *fs = FatFs;

    if (clst < 2 || clst >= fs->n_fatent)	/* Range check */
        return 1;

    switch (fs->fs_type) {
#if _FS_FAT12
    case FS_FAT12 : {
        UINT wc, bc, ofs;

        bc = (UINT)clst;
        bc += bc / 2;
        ofs = bc % 512;
        bc /= 512;
        if (ofs != 511) {
            if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
        } else {
            if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
            if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
        }
        wc = LD_WORD(buf);
        return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
    }
#endif
#if _FS_FAT16
    case FS_FAT16 :
        if (disk_readp(buf, fs->fatbase + clst / 256, ((UINT)clst % 256) * 2, 2)) break;
        return LD_WORD(buf);
#endif
#if _FS_FAT32
    case FS_FAT32 :
        if (disk_readp(buf, fs->fatbase + clst / 128, ((UINT)clst % 128) * 4, 4)) break;
        return LD_DWORD(buf) & 0x0FFFFFFF;
#endif
    }

    return 1;	/* An error occured at the disk I/O layer */
}
Beispiel #11
0
FRESULT pf_mount (
	FATFS *fs		/* Pointer to new file system object */
)
{
	BYTE fmt, buf[36] = {0};
	DWORD bsect, fsize, tsect, mclst;


	FatFs = 0;

	if (disk_initialize() & STA_NOINIT)	/* Check if the drive is ready or not */
		return FR_NOT_READY;

	/* Search FAT partition on the drive */
	bsect = 0;
	fmt = check_fs(buf, bsect);			/* Check sector 0 as an SFD format */
	if (fmt == 1) {						/* Not an FAT boot record, it may be FDISK format */
		/* Check a partition listed in top of the partition table */
		if (disk_readp(buf, bsect, MBR_Table, 16)) {	/* 1st partition entry */
			fmt = 3;
		} else {
			if (buf[4]) {					/* Is the partition existing? */
				bsect = LD_DWORD(&buf[8]);	/* Partition offset in LBA */
				fmt = check_fs(buf, bsect);	/* Check the partition */
			}
		}
	}
	if (fmt == 3) return FR_DISK_ERR;
	if (fmt) return FR_NO_FILESYSTEM;	/* No valid FAT patition is found */

	/* Initialize the file system object */
	if (disk_readp(buf, bsect, 13, sizeof (buf))) return FR_DISK_ERR;

	fsize = LD_WORD(buf+BPB_FATSz16-13);				/* Number of sectors per FAT */
	if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);

	fsize *= buf[BPB_NumFATs-13];						/* Number of sectors in FAT area */
	fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
	fs->csize = buf[BPB_SecPerClus-13];					/* Number of sectors per cluster */
	fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13);		/* Nmuber of root directory entries */
	tsect = LD_WORD(buf+BPB_TotSec16-13);				/* Number of sectors on the file system */
	if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
	mclst = (tsect						/* Last cluster# + 1 */
		- LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
		) / fs->csize + 2;
	fs->n_fatent = (CLUST)mclst;

	fmt = 0;							/* Determine the FAT sub type */
	if (_FS_FAT12 && mclst < 0xFF7)
		fmt = FS_FAT12;
	if (_FS_FAT16 && mclst >= 0xFF8 && mclst < 0xFFF7)
		fmt = FS_FAT16;
	if (_FS_FAT32 && mclst >= 0xFFF7)
		fmt = FS_FAT32;
	if (!fmt) return FR_NO_FILESYSTEM;
	fs->fs_type = fmt;

	if (_FS_32ONLY || (_FS_FAT32 && fmt == FS_FAT32))
		fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13));	/* Root directory start cluster */
	else
		fs->dirbase = fs->fatbase + fsize;				/* Root directory start sector (lba) */
	fs->database = fs->fatbase + fsize + fs->n_rootdir / 16;	/* Data start sector (lba) */

	fs->flag = 0;
	FatFs = fs;

	return FR_OK;
}
Beispiel #12
0
int main (int argc, char* argv[])
{
	UINT csz;
	HANDLE wh;
	DWORD wb, szvol;
	int ai = 1, truncation = 0;
	const char *outfile;


	/* Initialize parameters */
	if (argc >= 2 && *argv[ai] == '-') {
		if (!strcmp(argv[ai], "-t")) {
			truncation = 1;
			ai++;
			argc--;
		} else {
			argc = 0;
		}
	}
	if (argc < 3) {
		printf("usage: mkfatimg [-t] <source node> <output file> <volume size> [<cluster size>]\n"
				"    -t: Truncate unused area for read only volume.\n"
				"    <source node>: Source node\n"
				"    <output file>: FAT volume image file\n"
				"    <volume size>: Size of temporary volume size in unit of KiB\n"
				"    <cluster size>: Size of cluster in unit of byte (default:512)\n"
			);
		return 1;
	}
	strcpy(SrcPath, argv[ai++]);
	outfile = argv[ai++];
	RamDiskSize = atoi(argv[ai++]) * 2;
	csz = (argc >= 5) ? atoi(argv[ai++]) : 512;

	/* Create an FAT volume */
	f_mount(&FatFs, "", 0);
	if (f_mkfs("", 1, csz)) {
		printf("Failed to create FAT volume. Adjust volume size or cluster size.\n");
		return 2;
	}

	/* Copy directory tree onto the FAT volume */
	if (!maketree()) return 3;
	if (!Files) { printf("No file in the source directory."); return 3; }
	szvol = LD_WORD(RamDisk + BPB_TotSec16);
	if (!szvol) szvol = LD_DWORD(RamDisk + BPB_TotSec32);

	if (truncation) {
		DWORD ent, nent;
		DWORD szf, szfp, edf, edfp;
		DWORD szd, szdp, edd, eddp;

		/* Truncate unused root directory entries */
		if (FatFs.fs_type != FS_FAT32) {
			printf("\nTruncating unused root directory area...");
			for (nent = ent = 0; ent < FatFs.n_rootdir; ent++) {
				if (RamDisk[FatFs.dirbase * 512 + ent * 32]) nent = ent + 1;
			}
			szd = (nent + 15) / 16;
			szdp = FatFs.n_rootdir / 16;
			if (szd < szdp) {
				edd = FatFs.dirbase + szd;
				eddp = FatFs.database;
				MoveMemory(RamDisk + (edd * 512), RamDisk + (eddp * 512), (szvol - eddp) * 512);
				szvol -= szdp - szd;
				FatFs.database -= szdp - szd;
				ST_WORD(RamDisk + BPB_RootEntCnt, szd * 16);
			}
		}

		/* Truncate unused data area and FAT */
		printf("\nTruncating unused data area...");
		for (nent = ent = 2; ent < FatFs.n_fatent; ent++) {
			if (get_fat(&FatFs, ent)) nent = ent + 1;
		}
		switch (FatFs.fs_type) {
		case FS_FAT12:
			szf = (nent * 3 / 2 + (nent & 1) + 511) / 512;
			break;
		case FS_FAT16:
			szf = (nent * 2 + 511) / 512;
			if (nent - 2 < MIN_FAT16) nent = 0;
			break;
		default:
			szf = (nent * 4 + 511) / 512;
			if (nent - 2 < MIN_FAT32) nent = 0;
			break;
		}
		if (!nent) {
			printf("different FAT sub-type is needed. Adjust volume size or cluster size.\n");
			return 3;
		}
		szfp = LD_WORD(RamDisk + BPB_FATSz16) * RamDisk[BPB_NumFATs];
		if (!szfp) szfp = LD_DWORD(RamDisk + BPB_FATSz32) * RamDisk[BPB_NumFATs];
		edf = FatFs.fatbase + szf;
		edfp = (FatFs.fs_type == FS_FAT32) ? FatFs.database : FatFs.dirbase;
		MoveMemory(RamDisk + (edf * 512), RamDisk + (edfp * 512), (szvol - edfp) * 512);
		szvol -= (szfp - szf) + FatFs.csize * (FatFs.n_fatent - nent);
		if (FatFs.fs_type == FS_FAT32) {
			ST_DWORD(RamDisk + BPB_FATSz32, szf);
		} else {
			ST_WORD(RamDisk + BPB_FATSz16, szf);
		}
		RamDisk[BPB_NumFATs] = 1;
		if (szvol < 0x10000) {
			ST_WORD(RamDisk + BPB_TotSec16, szvol);
			ST_DWORD(RamDisk + BPB_TotSec32, 0);
		} else {
			ST_WORD(RamDisk + BPB_TotSec16, 0);
			ST_DWORD(RamDisk + BPB_TotSec32, szvol);
		}
	}

	/* Output the FAT volume to the file */
	printf("\nWriting output file...");
	wh = CreateFile(outfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
	if (wh == INVALID_HANDLE_VALUE) {
		printf("Failed to create output file.\n");
		return 4;
	}
	szvol *= 512;
	WriteFile(wh, RamDisk, szvol, &wb, 0);
	CloseHandle(wh);
	if (szvol != wb) {
		DeleteFile(argv[2]);
		printf("Failed to write output file.\n");
		return 4;
	}

	printf("\n%u files and %u directories in a %u bytes of FAT volume.\n", Files, Dirs, szvol);

	return 0;
}
Beispiel #13
0
void at_process(void)
{
   unsigned char received;
   void (*worker)(void) = NULL;

   static unsigned char heartbeat = 0x55;
    	
   ACTIVITYSTROBE(0);

   // port a holds the latched contents of the address bus a0-a3
   //
   LatchAddressIn();
   if (WASWRITE)
		LatchedAddress=LatchedAddressLast;
		
   //log0("%02X\n",LatchedAddress & ADDRESS_MASK);
			
   switch (LatchedAddress & ADDRESS_MASK)
   {
   case CMD_REG:
      {
         if (WASWRITE)
         {
			ReadDataPort();
            received = LatchedData;
#if (DEBUG_CMD)
	    log0("AVR CMD=0x%02x\n", received);
#endif
	    // File Group 0x10-0x17, 0x30-0x37, 0x50-0x57, 0x70-0x77
	    // filenum = bits 6,5
	    // mask1 = 10011000 (test for file group command)
	    // mask2 = 10011111 (remove file number)
	    if ((received & 0x98) == 0x10) {
	      filenum = (received >> 5) & 3;
	      received &= 0x9F;
	    }
	    
	    // Data Group 0x20-0x23, 0x24-0x27, 0x28-0x2B, 0x2C-0x2F
	    // filenum = bits 3,2
	    // mask1 = 11110000 (test for data group command)
	    // mask2 = 11110011 (remove file number)
	    if ((received & 0xf0) == 0x20) {
	      filenum = (received >> 2) & 3;
	      received &= 0xF3;
	    }
#if (PLATFORM!=PLATFORM_AVR)
            WriteDataPort(STATUS_BUSY);		// Busy handled in CPLD.
#endif
			//log0("%02X\n",LatchedData);
			
			// Directory group, moved here 2011-05-29 PHS.
			//
            if (received == CMD_DIR_OPEN)
            {
               // reset the directory reader
               //
               // when 0x3f is read back from this register it is appropriate to
               // start sending cmd 1s to get items.
               //
               worker = WFN_DirectoryOpen;
            }
            else if (received == CMD_DIR_READ)
            {
               // get next directory entry
               //
               worker = WFN_DirectoryRead;
            }
            else if (received == CMD_DIR_CWD)
            {
               // set CWD
               //
               worker = WFN_SetCWDirectory;
            }
			
			// File group.
			//
            else if (received == CMD_FILE_CLOSE)
            {
               // close the open file, flushing any unwritten data
               //
               worker = WFN_FileClose;
            }
            else if (received == CMD_FILE_OPEN_READ)
            {
               // open the file with name in global data buffer
               //
               worker = WFN_FileOpenRead;
            }
#ifdef INCLUDE_SDDOS
            else if (received == CMD_FILE_OPEN_IMG)
            {
               // open the file as backing image for virtual floppy drive
               // drive number in globaldata[0] followed by asciiz name.
               //
               worker = WFN_OpenSDDOSImg;
            }
#endif
            else if (received == CMD_FILE_OPEN_WRITE)
            {
               // open the file with name in global data buffer for write
               //
               worker = WFN_FileOpenWrite;
            }
            else if (received == CMD_FILE_OPEN_RAF)
            {
               // open the file with name in global data buffer for write/append
               //
               worker = WFN_FileOpenRAF;
            }
            else if (received == CMD_FILE_DELETE)
            {
               // delete the file with name in global data buffer
               //
               worker = WFN_FileDelete;
            }
            else if (received == CMD_FILE_GETINFO)
            {
               // return file's status byte
               //
               worker = WFN_FileGetInfo;
            }
            else if (received == CMD_FILE_SEEK)
            {
               // seek to a location within the file
               //
               worker = WFN_FileSeek;
            }
            else if (received == CMD_INIT_READ)
            {
			   // All data read requests must send CMD_INIT_READ before beggining reading
			   // data from READ_DATA_PORT. After execution of this command the first byte 
			   // of data may be read from the READ_DATA_PORT.
			   //
               WriteDataPort(globalData[0]);
			   globalIndex = 1;
			   LatchedAddress=READ_DATA_REG;
            }
			else if (received == CMD_INIT_WRITE)
            {
               // all data write requests must send CMD_INIT_WRITE here before poking data at 
			   // WRITE_DATA_REG	
               // globalDataPresent is a flag to indicate whether data is present in the bfr.
               //
               globalIndex = 0;
               globalDataPresent = 0;
            }
			else if (received == CMD_READ_BYTES)
			{	
				// Replaces READ_BYTES_REG
				// Must be previously written to latch reg.
				globalAmount = byteValueLatch;
				worker = WFN_FileRead;
			}
			else if (received == CMD_WRITE_BYTES)
			{
				// replaces WRITE_BYTES_REG
				// Must be previously written to latch reg.
				globalAmount = byteValueLatch;	
				worker = WFN_FileWrite;
			}

			// 
			// Exec a packet in the data buffer.
            else if (received == CMD_EXEC_PACKET)
            {
               worker = WFN_ExecuteArbitrary;
            }

#ifdef INCLUDE_SDDOS
         // SDDOS/LBA operations
         //
            else if (received == CMD_LOAD_PARAM)
            {
               // load sddos parameters for read/write
               // globalData[0] = img num
               // globalData[1..4 incl] = 256 byte sector number
               globalCurDrive = globalData[0] & 3;
               globalLBAOffset = LD_DWORD(&globalData[1]);
               WriteDataPort(STATUS_OK);
            }
            if (received == CMD_GET_IMG_STATUS)
            {
               // retrieve sddos image status
               // globalData[0] = img num
               WriteDataPort(driveInfo[byteValueLatch & 3].attribs);
            }
            if (received == CMD_GET_IMG_NAME)
            {
               // retrieve sddos image names
               //
               worker = WFN_GetSDDOSImgNames;
            }
            else if (received == CMD_READ_IMG_SEC)
            {
               // read image sector
               //
               worker = WFN_ReadSDDOSSect;
            }
            else if (received == CMD_WRITE_IMG_SEC)
            {
               // write image sector
               //
               worker = WFN_WriteSDDOSSect;
            }
            else if (received == CMD_SER_IMG_INFO)
            {
               // serialise the current image information
               //
               worker = WFN_SerialiseSDDOSDrives;
            }
            else if (received == CMD_VALID_IMG_NAMES)
            {
               // validate the current sddos image names
               //
               worker = WFN_ValidateSDDOSDrives;
            }
            else if (received == CMD_IMG_UNMOUNT)
            {
               // unmount the selected drive
               //
               worker = WFN_UnmountSDDOSImg;
            }
#endif

			//
			// Utility commands.
			// Moved here 2011-05-29 PHS
            else if (received == CMD_GET_CARD_TYPE)
            {
               // get card type - it's a slowcmd despite appearance
               disk_initialize(0);
               WriteDataPort(CardType);
            }
            else if (received == CMD_GET_PORT_DDR) // get portb direction register
            {
				WriteDataPort(IODDR);
            }
            else if (received == CMD_SET_PORT_DDR) // set portb direction register
            {
               IODDR = byteValueLatch;

               WriteEEPROM(EE_PORTBTRIS, byteValueLatch);
               WriteDataPort(STATUS_OK);
            }
            else if (received == CMD_READ_PORT) // read portb
            {
               WriteDataPort(IOPORT_R);
            }
            else if (received == CMD_WRITE_PORT) // write port B value
            {
               IOPORT_W = byteValueLatch;

               WriteEEPROM(EE_PORTBVALU, byteValueLatch);
               WriteDataPort(STATUS_OK);
            }
            else if (received == CMD_GET_FW_VER) // read firmware version
            {
               WriteDataPort(VSN_MAJ<<4|VSN_MIN);
            }
            else if (received == CMD_GET_BL_VER) // read bootloader version
            {
               WriteDataPort(blVersion);
            }
            else if (received == CMD_GET_CFG_BYTE) // read config byte
            {
               WriteDataPort(configByte);
            }
            else if (received == CMD_SET_CFG_BYTE) // write config byte
            {
               configByte = byteValueLatch;

               WriteEEPROM(EE_SYSFLAGS, configByte);
               WriteDataPort(STATUS_OK);
            }
            else if (received == CMD_READ_AUX) // read porta - latch & aux pin on dongle
            {
               WriteDataPort(LatchedAddress);
            }
            else if (received == CMD_GET_HEARTBEAT)
            {
               // get heartbeat - this may be important as we try and fire
               // an irq very early to get the OS hooked before its first
               // osrdch call. the psp may not be enabled by that point,
               // so we have to wait till it is.
               //
               WriteDataPort(heartbeat);
               heartbeat ^= 0xff;
            }
         }
      }
Beispiel #14
0
int load_wav (
	FIL *fp,			/* Pointer to the open file object to play */
	const char *title,	/* Title (file name, etc...) */
	void *work,			/* Pointer to working buffer (must be-4 byte aligned) */
	uint32_t sz_work	/* Size of working buffer (must be power of 2) */
)
{
	UINT md, wi, br, tc, t, btr;
	DWORD sz, ssz, offw, szwav, wsmp, fsmp, eof;
	WAVFIFO fcb;
	BYTE k, *buff = work;
	char *p, nam[NBSIZE], art[NBSIZE];


	xprintf("**** RIFF-WAVE Player ****\nFile=%s\n", title);	/* Put title */

	/* Is this a WAV file? */
	if (f_read(fp, buff, 12, &br) || br != 12) return -1;
	if (LD_DWORD(&buff[0]) != FCC('R','I','F','F')) return -1;
	if (LD_DWORD(&buff[8]) != FCC('W','A','V','E')) return -1;
	eof = LD_DWORD(&buff[4]) + 8;

	/* Analyze the RIFF-WAVE header and get properties */
	nam[0] = art[0] = 0;
	md = fsmp = wsmp = offw = szwav = 0;
	while (f_tell(fp) < eof) {
		if (f_read(fp, buff, 8, &br) || br != 8) return -1;
		sz = (LD_DWORD(&buff[4]) + 1) & ~1;
		switch (LD_DWORD(&buff[0])) {
		case FCC('f','m','t',' ') :	/* fmt chunk */
			if (sz > 1000 || sz < 16 || f_read(fp, buff, sz, &br) || sz != br) return -1;
			if (LD_WORD(&buff[0]) != 0x1) return -1;	/* Check if LPCM or not */
			if (LD_WORD(&buff[2]) == 2) {	/* Check channels (1 or 2) */
				md = 1; wsmp = 2;
			} else {
				md = 0; wsmp = 1;
			}
			if (LD_WORD(&buff[14]) == 16) {	/* Resolution (8 or 16) */
				md |= 2; wsmp *= 2;
			}
			fsmp = LD_DWORD(&buff[4]);		/* Sampling rate */
			break;

		case FCC('f','a','c','t') :	/* fact chunk */
			f_lseek(fp, f_tell(fp) + sz);
			break;

		case FCC('d','a','t','a') :	/* data chunk */
			offw = f_tell(fp);	/* Wave data start offset */
			szwav = sz;			/* Size of wave data [byte] */
			f_lseek(fp, f_tell(fp) + sz);
			break;

		case FCC('L','I','S','T'):	/* LIST chunk */
			sz += f_tell(fp);
			if (f_read(fp, buff, 4, &br) || br != 4) return -1;
			if (LD_DWORD(buff) == FCC('I','N','F','O')) {	/* LIST/INFO sub-chunk */
				while (f_tell(fp) < sz) {
					if (f_read(fp, buff, 8, &br) || br != 8) return -1;
					ssz = (LD_DWORD(&buff[4]) + 1) & ~1;
					p = 0;
					switch (LD_DWORD(buff)) {
					case FCC('I','N','A','M'):		/* INAM (name) field */
						p = nam; break;
					case FCC('I','A','R','T'):		/* IART (artist) field */
						p = art; break;
					}
					if (p && ssz <= NBSIZE) {
						if (f_read(fp, p, ssz, &br) || br != ssz) return -1;
					} else {
						if (f_lseek(fp, f_tell(fp) + ssz)) return -1;
					}
				}
			} else {
				if (f_lseek(fp, sz)) return -1;	/* Skip unknown sub-chunk */
			}
			break;

		default :	/* Unknown chunk */
			return -1;
		}
	}
	if (!szwav || !fsmp) return -1;		/* Check if valid WAV file */
	if (f_lseek(fp, offw)) return -1;	/* Seek to top of wav data */
	tc = szwav / fsmp / wsmp;			/* Length (sec) */

	xprintf("IART=%s\nINAM=%s\n", art, nam);
	xprintf("Sample=%u.%ukHz/%ubit/%s\nLength=%u:%02u\n", fsmp / 1000, (fsmp / 100) % 10, (md & 2) ? 16 : 8, (md & 1) ? "Stereo" : "Mono", tc / 60, tc % 60);

	/* Initialize sound FIFO and start sound streming */
	fcb.mode = md;			/* Sampling: b0=mono(0)/stereo(1), b1=8bit(0)/16bit(1) */
	fcb.buff = buff;		/* Pointer to streaming buffer */
	fcb.sz_buff = sz_work;	/* Size of streaming buffer */
	if (!sound_start(&fcb, fsmp)) return -1;	/* Start sound streaming */

	k = 0; wi = 0;
	while (szwav || fcb.ct >= 4) {	/* Sount streaming loop */
		if (szwav && fcb.ct <= sz_work / 2) {	/* Refill FIFO when it gets half empty */
			btr = (szwav >= sz_work / 2) ? sz_work / 2 : szwav;
			f_read(fp, &buff[wi], btr, &br);
			if (br != btr) break;	/* Exit if illigal file termination or FS error */
			szwav -= br;
			wi = (wi + br) & (sz_work - 1);
			IEN(CMT3, CMI3) = 0;	/* Disable CMT3 compare match irq */
			fcb.ct += br;
			IEN(CMT3, CMI3) = 1;	/* Enable CMT3 compare match irq */
		}
		if (scif_test()) {		/* Exit if a user command arrived */
			k = scif_getc();
			break;
		}
		t = (f_tell(fp) - offw - fcb.ct) / fsmp / wsmp;	/* Refresh time display every 1 sec */
		if (t != tc) {
			tc = t;
			xprintf("\rTime=%u:%02u", tc / 60, tc % 60);
		}
	}

	sound_stop();	/* Stop sound streaming */

	xputc('\n');
	return k;	/* Terminated due to -1:error, 0:eot, >0:key code */
}