Skip to content

Instantly share code, notes, and snippets.

@asb2m10
Last active April 16, 2018 15:20
Show Gist options
  • Select an option

  • Save asb2m10/762d250f4479fb04b0bce2c0b6db3fb7 to your computer and use it in GitHub Desktop.

Select an option

Save asb2m10/762d250f4479fb04b0bce2c0b6db3fb7 to your computer and use it in GitHub Desktop.
Forked version of EpsLin - https://sites.google.com/site/epslin4free/ for the Ensoniq EPS. I've removed the requirement of the floppy. I use this to create EDE (disk) files from EFE (instruments).
#!/bin/bash
# Translate a EFE EPS file to [HFE](http://hxc2001.free.fr/floppy_drive_emulator/).
efe2hfe () {
efefile=`basename $1`
filename="${efefile%%.*}"
rm -f $filename.img
rm -f $filename.ede
epslin -fi $filename.img eps
epslin -p1 $filename.img $efefile
touch $filename.ede
epslin -c $filename.img $filename.ede
rm $filename.img
/Users/asb2m10/opt/hxcfe_cmdline/App/hxcfe -finput:$filename.ede -conv:HXC_HFE
rm $filename.ede
}
if [ -z "$1" ] ; then
for i in `ls *.ede`; do
efe2hfe $i
done
else
efe2hfe $1
fi
/////////////////////////////////////////////////////
//
// EpsLin v1.42 (c) Juha Forsten 5 Aug / 2006
// -------------------------------------------------
// * File utility for Ensoniq samplers (EPS/ASR)
//
//
// ------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -------------------------------------------------------------------------
//
// TO COMPILE:
// ===========
//
// Should compile in Linux and Windows (Cygwin) just typing:
//
// gcc EpsLin_v1.42.c -o epslin
//
// In windows you have to install "fdrawcmd.sys" from
// http://simonowen.com/fdrawcmd/
//
// and get the header file from
// http://simonowen.com/fdrawcmd/fdrawcmd.h
//
// and put it in the same dir as the EpsLin source
//
// HISTORY
// =======
//
// v.1.43: [FUTURE..]
// - Optional "allowed" devices list to minimize
// unintentional writes to devices like system
// hard disk etc.. for Format and ImageCopy
// THIS COULD SAVE YOUR DAY (or even two)..!
// - Check mode and only efe erase/put use the
// 'I' write to check if 's' media type..
// - Use 's' media type in Get and in GetFat/SetFat
//
// v.1.42:
// - [Windows] Had to optimize the I/O functions involved
// when Efes are GET/ERASED/PUT from/to media. This increased
// the run time memory consumption, as the whole FAT
// table are loaded to memory in order to avoid
// seeks in CD-ROM (/dev/scd) and to write Iomega
// Zip-drives which don't support single byte writes.
// As the load/save time of the FAT table depends on the size
// of the media, it _might_ take quite a long time for some media,
// thus making the get/put/erase slow. As the Zip drive is the only
// device to test this, it happens to take only 2 seconds to
// read+write the table, so it's quite reasonable.
// If you send me a SCSI device, that is very slow for this reason,
// I'll try to optimize the functions more - until that,
// for me it's fast enough.. ;-)
// - Options that accept parameter 'a' (= all), now starts
// at idx 1 (not 0 as previous versions).
// - Added progress info when Efes are put/get.
//
// v.1.41:
// - [Windows] Added support for /dev/scd layer in Cygwin..
// Since the seeks are posible only in 2048 byte multiples
// had to make some mods to ReadBlock etc. functions.
// Minor penalties in performance..
//
// v.1.40: NOW PORTED TO WINDOWS!!
// - Uses Simon Owens "fdrawcmd.sys" (http://simonowen.com/fdrawcmd/)
// driver for low-level floppy access. Thank's Simon!
// - Minor differencies between Cygwin (Win32) and Linux in command
// line arguments (for ex. Cygwin requires allways parameter for -p)
// - Should support also SCSI devices trough Cygwin layer
// - Some minor fixes
//
// v.1.37:
// - Fixed nasty bug in dir-argument (-d) parsing, that
// sometimes leads an error "ERROR: Index '0' is not a directory!".
// Hopefully now solved..
// - More investigation had to be done to find out how EPS knows, when to
// load Song (instuments has the mask,that tells what location to load -
// for song there are no such info). It seems that if index is 0, it is
// not counted as a valid song, so no song data is loaded.
// The BankInfo function is modified based on that knowledge.
//
// BTW: You can make deeper dir structures with EPS than banks can handle, so..
// don't do it if you want to use files in those dirs with banks.. :-)
//
// - Minor changes to BankInfo output. Paths starts with '/' and ends with no '/'
//
//
// v.1.36:
// - Option to join multifile EFEs to single EFE file
//
// v.1.35:
// - Added missing CR,LF,EOF bytes to EFE header (cosmetic)
// - Option to show info from Ensoniq Bank EFE
// - Option to split EFE to multifile parts added
// - Option to print directory listing in compact mode to make the
// parsing for external programs easier.
// - Some code clean-ups...
//
// v.1.34:
// - Support for Multi Files (ie. instruments, that don't fit in one floppy)
// - Fixed (new) gcc errors
//
// NOTES!
// ======
//
//
// * Some _commercial_ EPS/ASR tools corrupts the FAT.. You should avoid
// those programs.. IF you have to use them, please at least check
// the disks and image-files before use with EpsLin 'check' option (-C).
// If you use those corrupted disk/images you may loose data!!
//
// TODO:
// =====
//
// [CYGWIN]:
// !! PutEfe doesn't work without idx number.. It's the Optget that
// doesn't support optional arguments, so we'll wait for proper version...
//
// [GENERAL]
//
// !! Format -fi optimize (now redundancy in allocated fat_block write)
//
// !! MkDir max level.. (Bank can load files only max 11-level deep dirs)
//
// !! Fix MKDIR Kludge in PutEFE...
//
// !! Using Floppy with ReadImage sometimes mess up the FD controller !?
//
// !! Add 'image copy' -feature (ie. make it possible to transfer
// data in SCSI HD <-> ZIP, Zip requires '0x6d' at first byte in disk)
//
// ! WAV to EFE & EFE to WAV conversions.
//
// ! In EPS, the OS has to be in one contiguos part
// * ASR don't mind...
//
// - Dir-transfer function (copy files recursively..)
// Usefull to transfer whole dir structures from medium to an another.
// (Must take care of changing SCSI-ID in Bank-files ?)
//
// - Erase: Recurse Dirs !!
//
// - Format_n_Write -support (?!)
//
// - First block not used by EPS/ASR. Write some info to that block ie. use
// it as a "comments & info" for that disk.. The first letter has to be
// 'm' (='0x6d).. see above.
//
// Uncommnet to enter debug state...
#define DEBUG
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#define O_BINARY 0 // In windows open is set to binary mode
// In linux this is not defined so set it to 0
// (this walue is ORed, so no harm is done..)
#define VERSION "v1.42"
#define FIRST_BLOCK_MESSAGE "Created with EpsLin for Linux"
#define BLOCK_SIZE 512
#define DIR_BLOCKS 2
#define DIR_START_BLOCK 3
#define DIR_END_BLOCK 4
#define MAX_DIR_DEPTH 10
#define ID_BLOCK 1
#define OS_BLOCK 2
#define DISK_LABEL_SIZE 8
#define MAX_NUM_OF_DIR_ENTRIES 39
#define EFE_SIZE 26
#define FAT_START_BLOCK 5
#define MAX_DISK_SECT 20
#define EPS_IMAGE_SIZE 819200
#define ASR_IMAGE_SIZE 1638400
// Buffer size for image copy
#define IMAGE_COPY_BUFFER_BLOCKS 100
#define DEFAULT_DISK_LABEL "DISK000 "
#define EDE_LABEL "EPS-16 Disk"
#define EDE_SKIP_START 0xA0
#define EDE_SKIP_SIZE 200
#define EDE_ID 0x03
#define EDA_LABEL "ASR-10 Disk"
#define EDA_SKIP_START 0x60
#define EDA_SKIP_SIZE 400
#define EDA_ID 0xCB
// Imagefile types
#define EPS_TYPE 'e'
#define ASR_TYPE 'a'
#define GKH_TYPE 'g'
#define EDE_TYPE 'E'
#define EDA_TYPE 'A'
#define OTHER_TYPE 'o'
//Modes for Bank Info
#define MODE_EPS 4
#define MODE_E16 23
#define MODE_ASR 30
// OS version info offsets (in EFE)
#define EPS_OS_POS 0x3A8
#define E16_OS_POS 0x390
#define ASR_OS_POS 0x6F2
// Modes
#define NONE 0
#define READ 1
#define WRITE 2
#define GET 3
#define PUT 4
#define ERASE 5
#define MKDIR 6
#define FORMAT 7
#define TEST 99
// Print modes
#define HUMAN_READABLE 0
#define COMPUTER_READABLE 1
// Return values
#define ERR -1
#define OK 0
// Error print-out & exit
#ifdef DEBUG
#define EEXIT(args) (fprintf(stderr,"(line: %d) ",__LINE__), fprintf args, exit(ERR))
#else
#define EEXIT(args) (fprintf args, exit(ERR))
#endif
// For 'getopt'
extern char *optarg;
extern int optind, opterr, optopt;
// Datatype for floppy disk access
typedef int FD_HANDLE;
// Temp-file name
static char tmp_file[13] = "EpsLinXXXXXX";
//static char tmp_file[64];
// Declaration of ReadBlocks
int ReadBlocks(char media_type, FD_HANDLE fd, int file, unsigned int start_block,
unsigned int length, unsigned char *buffer);
// Temp-file cleanup -function (called by 'atexit')
static void CleanTmpFile(void) {
unlink(tmp_file);
}
// EPS/ASR-file types
static char *EpsTypes[40]={
// 0 1 2 3 4 5 6 7 8 9
"(empty)","EPS-OS ","DIR/ ","Instr ","EPS-Bnk","EPS-Seq","EPS-Sng","EPS-Sys",".. / ","EPS-Mac",
// 10 11 12 13 14 15 16 17 18 19
" "," "," "," "," "," "," "," "," "," ",
// 20 21 22 23 24 25 26 27 28 29
" "," "," ","E16-Bnk","E16-Eff","E16-Seq","E16-Sng","E16-OS ","ASR-Seq","ASR-Sng",
// 30 31 32 33 34 35 36 37 38 39
"ASR-Bnk","ASR-Trk","ASR-OS ","ASR-Eff"," "," "," "," "," "," ??? ",
};
//////////////
// ShowUsage
void ShowUsage()
{
printf("\nEpsLin %s (c) J. Forsten (%s)\n", VERSION, __DATE__);
printf("==========================================\n");
printf("\nUsage: epslin [options] [imagefile or device] [Efe #0] [Efe #1] ... [Efe #N]\n\n");
printf("Options:\n-------- \n\n");
printf(" -r READ image from disk. (Disk type (EPS/ASR) is autodetected!)\n");
printf(" File extension (img/ede/eda) selects the format.\n\n");
printf(" -w WRITE image to disk. (Disk type (EPS/ASR) is autodetected!)\n");
printf(" File extension (img/gkh/ede/eda) selects the format.\n\n");
printf(" -fe,-fa, -fi FORMAT disk/image/device (a=asr, e=eps, i=image/device)\n");
printf(" Use '-l' option to define disk label.\n");
printf(" If imagefile doesn't exists it will be created. \n");
printf(" Image size is then needed as an last argument.\n");
printf(" Size is in bytes ('K' and 'M' can be used as a suffix)\n");
printf(" If EPS/ASR DISK image is wanted, use size 'eps' or 'asr'\n");
printf(" instead of numeric values!! See examples..\n\n");
printf(" Examples: 'epslin -fe' : Format EPS-Disk\n");
printf(" 'epslin -fa' : Format ASR-Disk\n");
printf(" 'epslin -fi epsdisk.img eps' : Create EPS disk image\n");
printf(" 'epslin -fi asrdisk.img asr' : Create ASR disk image\n");
printf(" 'epslin -fi MyImage.img' : Format MyImage.img\n");
printf(" NOTE: File exists!\n");
printf(" 'epslin -fi MyCDROM.img 650M' : Create and format\n");
printf(" file size 650MB\n");
printf(" 'epslin -l EpsHD -fi /dev/sda : Format SCSI disk\n");
printf(" : with label 'EpsHD'\n");
printf(" -c CONVERT imagefile from one format to another.\n");
printf(" Supported conversions:\n");
printf(" .img -> ede (EPS)\n");
printf(" .img -> eda (ASR)\n");
printf(" .gkh -> img (EPS)\n");
printf(" .ede -> img (EPS)\n");
printf(" .eda -> img (ASR)\n");
printf(" Examples: 'epslin -c my_disk.img my_disk.ede'\n\n");
printf(" -g index_list \n");
printf(" GET Efe(s) from image/dev.\n");
printf(" Examples: -g1,2,4 : Efe's 1,2 and 4.\n");
printf(" -g10-20 : from 10 to 20.\n");
printf(" -g10- : from 10 to end.\n");
printf(" -g1,3-5,8 : 1,3 to 5 and 5.\n");
printf(" -ga : All from that dir.\n\n");
printf(" -p [start_index] \n");
printf(" PUT Efe(s) to image/dev. The efe is saved to the\n");
printf(" first empty index found. The search of empty index\n");
printf(" can be set to start at start_index (default=1).\n");
printf(" The Efe-files must be defined after image-file.\n");
printf(" Examples: -p efe_files.efe : Put Efe in the first \n");
printf(" empty index.\n");
printf(" -p *.efe : Put all efes found in\n");
printf(" the current dir.\n");
printf(" -p0 os_file.efe : Put Operating System\n");
printf(" to index 0.\n\n");
printf(" -e index_list \n");
printf(" ERASE Efe(s) from image/dev.\n\n");
printf(" -d path DIRECTORY definition for most operations. \n");
printf(" Use sub-directory _numbers_.\n");
printf(" Example: -d12/4/7\n\n");
printf(" -m dir_name MAKE directory.\n\n");
printf(" -C level CHECK the disk/image. Gives detailed info\n");
printf(" about the structure of the disk/image.\n");
printf(" Level can be either 0 or 1.\n\n");
printf(" -s efe_to_split slice_type\n");
printf(" SPLIT big Efe to smaller pieces.\n");
printf(" Example: -s Big.efe eps : Slices to fit in EPS-Disk\n");
printf(" Example: -s Big.efe asr : Slices to fit in ASR-Disk\n\n");
printf(" -b Bank.efe BANK-info. Prints useful(?) inside info about bank efe\n\n");
printf(" -P PARSE-friendly output. Use with GUI/Fortned-softwares\n\n");
printf("Image_file = Ensoniq(EPS/ASR)-Disk imagefile\n\n");
}
///////////////
// ParseRange
void ParseRange(char *optarg, char process_efe[MAX_NUM_OF_DIR_ENTRIES])
{
size_t ssize;
char tmp_str[80];
int from_efe,to_efe,i;
strcpy(tmp_str,optarg);
ssize = strspn(tmp_str,"0123456789");
tmp_str[ssize]='\0';
from_efe= atoi(tmp_str);
if(strlen(optarg)== ssize+1) {
to_efe=MAX_NUM_OF_DIR_ENTRIES-1;
} else {
to_efe= atoi(tmp_str+ssize+1);
}
// Mark the range of efes
for(i=from_efe;i<=to_efe;i++) process_efe[i]=1;
}
////////////////
// ParseList
void ParseList(char *optarg, char process_efe[MAX_NUM_OF_DIR_ENTRIES])
{
size_t ssize;
char tmp_str[80];
int j;
strcpy(tmp_str,optarg);
j=0;
// Slice the argument using ',' as a separator.
while((ssize = strspn(tmp_str+j,"0123456789-")) != 0) {
tmp_str[ssize+j]='\0';
// List element is 'range'
if((index(tmp_str+j,'-')) != NULL) {
ParseRange(tmp_str+j,process_efe);
} else {
process_efe[atoi(tmp_str+j)] = 1;
}
j=j+(ssize+1);
}
}
/////////////////////////
// ParseEntry
void ParseEntry(char *optarg, char process_efe[MAX_NUM_OF_DIR_ENTRIES])
{
char *idx_new;
int i;
// All?
if(strcmp(optarg,"a")==0) {
//Mark all
for(i=1;i < MAX_NUM_OF_DIR_ENTRIES; i++) process_efe[i]=1;
} else {
// List ?
if((idx_new=index(optarg,',')) == NULL) {
// Range ?
if(index(optarg,'-')) {
ParseRange(optarg,process_efe);
} else {
// One number - Mark it
process_efe[atoi(optarg)]=1;
}
} else {
ParseList(optarg,process_efe);
}
}
}
//////////////////////
// ParseDir
int ParseDir(char *dirpath_str, unsigned int *DirPath, unsigned int *subdir_cnt)
{
char *idx_new, *idx, dir_str[80];
// Validity check for 'dirpath_str' ie. can't
// be over 70 characters (even that's too much!)
if(strlen(dirpath_str) > 70) {
EEXIT((stderr,"ERROR: Invalid directory path '%s'.\n",dirpath_str));
}
// Clear the 'dir_str'-buffer so that
// parsing doesn't fail if buffer contains
// character '/' at the "right" place.. (ie. bug fix :-)
dir_str[strlen(dirpath_str)+1]= 0;
// Make a copy of path string
strcpy(dir_str,dirpath_str);
// Check if path starts with '/'
if(dir_str[0] == '/') {
if(dir_str[1] == '\0') return(OK); else dir_str[0]=' ';
}
*subdir_cnt=0;
// Parse 'path'
if(dir_str[strlen(dir_str)-1] != '/') {
dir_str[strlen(dir_str)]='/';
dir_str[strlen(dir_str)+1]='\0';
}
idx= dir_str;
while((idx_new= (char *) index(idx,'/')) != NULL) {
*idx_new= '\0';
DirPath[*subdir_cnt]=atoi(idx);
idx= idx_new+1;
(*subdir_cnt)++;
}
return(OK);
}
////////////////////
// Name to DosName
void DosName(register char *dosname, char *name)
{
register char *p;
strcpy(dosname,name);
while((p=(char *) strchr(dosname,'*'))!=NULL) {
*p='#';
}
// Uncomment if 'space' to '_' -conversion needed
/*
strcpy(dosname,name);
while((p=strchr(dosname,' '))!=NULL) {
*p='_';
}
*/
strcat(dosname,".efe");
}
////////////////////////////////
// Print the Dir-List (EFEs)
void PrintDir(unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE], unsigned int mode,
char process_efe[MAX_NUM_OF_DIR_ENTRIES], char in_file[FILENAME_MAX],
char media_type, char *DiskLabel, unsigned int free_blks, unsigned int used_blks,
int printmode)
{
unsigned int size, cont, start;
unsigned int type, real_type, j, k;
char name[13],dosname[17];
char media[FILENAME_MAX];
char type_text[9];
switch (media_type)
{
case 'f':
strcpy(media,"FILE: ");
strcat(media,in_file);
break;
case 'e':
strcpy(media,"EPS-DISK ");
//strcat(media,DiskLabel);
break;
case 'a':
strcpy(media,"ASR-DISK ");
//strcat(media,DiskLabel);
break;
}
// Print DirectoryList
// ===================
if(printmode== HUMAN_READABLE) {
printf("\n------------------------------------------+---------------------------------+\n");
printf(" Disk Label: %-28s |", DiskLabel);
printf(" %-31s |\n", media);
printf("------+----------+--------------+---------+------------------+--------------+\n");
printf(" Idx |Type | Name |Blocks | FileName | FileSize |\n");
printf("------+----------+--------------+---------+------------------+--------------+\n");
} else {
//Computer readable: Label,media, used block, used bytes, free blocks, free bytes
printf("%s,%s,%d,%ld,%d,%ld\n",DiskLabel,media, used_blks, (unsigned long) (used_blks)*512, free_blks, (unsigned long) (free_blks)*512);
}
for(j=0;j<MAX_NUM_OF_DIR_ENTRIES;j++){
//Name
for(k=0;k<12;k++) {
name[k]=Efe[j][k+2];
}
name[12]=0;
DosName(dosname,name);
size =(unsigned int) ((Efe[j][14] << 8) + Efe[j][15]);
cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
start=(unsigned long) ((Efe[j][18] << 24)+ (Efe[j][19] << 16) +
(Efe[j][20] << 8 ) + Efe[j][21]);
type=Efe[j][1];
real_type=type;
// Check If type in unknown
if(type>39) {
type=39;
}
//if(1) {
if(type!=0) {
if(printmode == HUMAN_READABLE) {
if(process_efe[j] == 1) {
switch(mode)
{
case GET:
printf("<-");
break;
case PUT:
case MKDIR:
printf("->");
break;
case ERASE:
printf("!!");
break;
default:
break;
}
} else {
printf(" ");
}
}
if(printmode == HUMAN_READABLE) {
if((type==2) || (type==8)) {
printf(" %02d | %s | %-12s | | | |\n",j,EpsTypes[type],name);
} else {
if(type!=0) {
strcpy(type_text,EpsTypes[type]);
if( Efe[j][22] != 0) {
type_text[5]='\0';
sprintf(type_text,"%s(%2d)",type_text,Efe[j][22]);
printf(" %02d | %s| %-12s | %7d | %s | %12ld |\n",j,type_text,name ,size,dosname, (unsigned long) (size+1)*512);
} else {
printf(" %02d | %s | %-12s | %7d | %s | %12ld |\n",j,type_text,name ,size,dosname, (unsigned long) (size+1)*512);
}
}
} // else
} else {
// Computer readable
printf("%d,%s,%d,%s,%d,%d,%s,%ld\n",j, EpsTypes[type], real_type, name,Efe[j][22], size, dosname, (unsigned long) (size+1)*512);
}
// This line is for debuggin. Uncomment it if needed
printf(" %02d | %s(%d) | %-12s | %4d | start=%d(%x) , cont=%d(%x) |\n",j,EpsTypes[type],real_type,name ,size, start,start,cont,cont);
}
//else if (printmode == COMPUTER_READABLE) {
// If empty dir entry in this index, print "null" line for easier coputer parsing...
// printf("%d,%s,%d,%s,%d,%d,%s,%ld\n",j, "(empty)",0 ,"", 0,0,"",0);
//}
}
if(printmode == HUMAN_READABLE) {
printf("------+----------+--------------+---------+---------------------------------+\n");
printf(" Used: %23d Blocks | Used: %16ld Bytes |\n", used_blks, (unsigned long) (used_blks)*512);
printf(" Free: %23d Blocks | Free: %16ld Bytes |\n", free_blks, (unsigned long) (free_blks)*512);
printf("----------------------------------------------------------------------------+\n");
printf(" Total: %23d Blocks | Total:%16ld Bytes |\n", free_blks+used_blks, (unsigned long) (free_blks+used_blks)*512);
printf("----------------------------------------------------------------------------+\n\n");
}
}
/////////////////////////////////////
// PrintBankInfo
// =============
// - Prints the structure of bank including
// instruments and songs.
int PrintBankInfo(char filename[FILENAME_MAX], int printmode)
{
int mode,count;
int instValid[8];
int effectFound=0;
int fd;
int i,j,k;
unsigned char data[1024];
if(printmode == COMPUTER_READABLE) {
// COMPUTER READABLE
//Open & Read
if( (fd=open(filename, O_RDONLY | O_BINARY, 0)) <= 0) {
printf("1\n");
return(1);
}
if((count=read(fd,data,0x222)) < 0x222) {
printf("1\n");
return(1);
}
// Get Bank type
if((data[0x32] != 4) && (data[0x32] != 23) && (data[0x32] != 30)) {
printf("2\n");
return(1);
}
// OK
printf("0\n");
// Bank Type
mode=data[0x32];
printf("%d\n",mode);
// Check Num of Blocks
if(data[0x35] > 3) {
effectFound = 1;
}
// Bank Name
for(i=0x208;i<0x220;i=i+2) {
printf("%c",data[i]);
}
//Mask
printf("\n%d\n",data[0x220]);
instValid[7] = (data[0x220] >> 7) & 0x01;
instValid[6] = (data[0x220] >> 6) & 0x01;
instValid[5] = (data[0x220] >> 5) & 0x01;
instValid[4] = (data[0x220] >> 4) & 0x01;
instValid[3] = (data[0x220] >> 3) & 0x01;
instValid[2] = (data[0x220] >> 2) & 0x01;
instValid[1] = (data[0x220] >> 1) & 0x01;
instValid[0] = data[0x220] & 0x01;
for(j=0;j<9;j++) {
//eps
if(mode==MODE_EPS) {
read(fd,data,16);
} else if(mode==MODE_E16) {
read(fd,data,16);
} else {
read(fd,data,28);
}
// Valid instrument?
if(j<8) {
if(!instValid[j]) {
printf("0\n");
continue;
}
} else {
// Valid song ?
if(data[4] == 0) {
printf("0\n");
continue;
}
}
// Inst/Song info
if(data[0] > 0x7f) {
//Song?
if(j==8) {
printf("0\n");
} else {
// "Copy of" + Inst num
printf("2,%d\n",(data[0] & 0x0f)+1);
}
} else {
//"Valid" + Path Depth
printf("1,%d,",data[0]);
// Device
printf("%d,",data[2]);
//Media Name (if any)
if(mode==MODE_EPS) {
printf("<NONE>,");
} else {
printf("%c%c%c%c%c%c%c,",
data[ 3],
data[ 5],
data[ 7],
data[ 9],
data[11],
data[13],
data[15]);
}
if(data[0] > 0) {
for(k=0;k<data[0];k++) {
printf("/%d",data[ 4+2*k]);
}
printf(",%d\n",data[4+2*k]);
} else {
printf("/,%d\n",data[4]);
}
}
}
if(effectFound) {
lseek(fd,0x800,0);
read(fd,data,64);
printf("1,%c%c%c%c%c%c%c%c%c%c%c%c\n",
data[10],
data[12],
data[14],
data[16],
data[18],
data[20],
data[22],
data[24],
data[26],
data[28],
data[30],
data[32]);
} else {
printf("0\n");
}
} else {
// HUMAN READABLE
if( (fd=open(filename, O_RDONLY | O_BINARY, 0)) <= 0) {
printf("ERROR:File not found!\n");
return(1);
}
if( (count=read(fd,data,0x222)) < 0x222) {
printf("ERROR:File read error!\n");
return(1);
}
// Get Bank type
switch (data[0x32]) {
case 4:
mode=MODE_EPS;
printf("Bank type:EPS\n");
break;
case 0x17:
mode=MODE_E16;
printf("Bank type:EPS16+\n");
break;
case 0x1e:
mode=MODE_ASR;
printf("Bank type:ASR\n");
break;
default:
printf("ERROR: Not an Ensoniq Bank file!\n");
exit(1);
}
// Check Num of Blocks
if(data[0x35] > 3) {
effectFound = 1;
}
printf("Bank Name:");
for(i=0x208;i<0x220;i=i+2) {
printf("%c",data[i]);
}
printf("\n");
printf("Inst Mask:0x%x (%d%d%d%d%d%d%d%d)\n",data[0x220],
(data[0x220] >> 7) & 0x01,
(data[0x220] >> 6) & 0x01,
(data[0x220] >> 5) & 0x01,
(data[0x220] >> 4) & 0x01,
(data[0x220] >> 3) & 0x01,
(data[0x220] >> 2) & 0x01,
(data[0x220] >> 1) & 0x01,
data[0x220] & 0x01);
for(j=0;j<9;j++) {
if(j==8) {
printf("\nSONG\n");
} else {
printf("\nINST %d\n",j+1);
}
//eps
if(mode==MODE_EPS) {
read(fd,data,16);
} else if(mode==MODE_E16) {
read(fd,data,16);
} else {
read(fd,data,28);
}
if(data[0] >= 0x80) {
if(j==8) {
printf("<NONE>\n");
} else {
printf("Copy Of Inst: %d\n",(data[0] & 0x0f)+1);
}
} else if (data[0] == 0x7f) {
printf("Deleted\n");
} else {
printf("Path Depth: %d (0x%x)\n",data[0],data[0]);
printf("0xFF: 0x%x\n",data[1]);
printf("Media (0=floppy, SCSI+1): 0x%x\n",data[2]);
printf("Disk Label: %c%c%c%c%c%c%c\n",
data[ 3],
data[ 5],
data[ 7],
data[ 9],
data[11],
data[13],
data[15]);
if(data[0] > 0) {
printf("Path:");
for(k=0;k<data[0];k++) {
printf("/%d",data[ 4+2*k]);
}
printf("\nInst Idx:%d\n",data[4+2*k]);
} else {
printf("Inst Idx:%d\n",data[4]);
}
}
}
if(effectFound) {
lseek(fd,0x800,0);
read(fd,data,64);
printf("\nEFFECT: %c%c%c%c%c%c%c%c%c%c%c%c\n\n",
data[10],
data[12],
data[14],
data[16],
data[18],
data[20],
data[22],
data[24],
data[26],
data[28],
data[30],
data[32]);
}
}
return(0);
}
/////////////////////////////////
// Get FAT entry - use fat-table
unsigned int GetFatEntry(char media_type, unsigned char *DiskFAT, int file, unsigned int block)
{
unsigned int fatsect, fatpos,tmp;
unsigned char FatEntry[3];
fatsect= (int) block / 170;
fatpos = block % 170;
if(media_type=='f') {
// FILE ACCESS
if(lseek(file,(FAT_START_BLOCK+fatsect)*BLOCK_SIZE+fatpos*3, SEEK_SET) == -1) {
printf("ERROR in seek\n");
}
if(read(file,FatEntry,3) == 0) {
printf("ERROR in read\n");
}
return((FatEntry[0] << 16) + (FatEntry[1] << 8) + FatEntry[2]);
} else {
// DISK ACCESS - uses FAT-table
tmp = (fatsect*BLOCK_SIZE) + fatpos*3;
return((DiskFAT[tmp] << 16) + (DiskFAT[tmp+1] << 8) + DiskFAT[tmp+2]);
}
}
/////////////////////
// PutFatEntry
int PutFatEntry(char media_type, unsigned char *DiskFAT, int file,
unsigned int block, unsigned int fatval)
{
unsigned int fatsect, fatpos,tmp;
unsigned char FatEntry[3];
fatsect= (int) block / 170;
fatpos = block % 170;
FatEntry[2] = fatval & 0x000000FF;
FatEntry[1] = (fatval >> 8) & 0x000000FF;
FatEntry[0] = (fatval >> 16) & 0x000000FF;
if(media_type=='f') {
// file access
lseek(file,(FAT_START_BLOCK+fatsect)*BLOCK_SIZE+fatpos*3, SEEK_SET);
write(file,FatEntry,3);
return(OK);
} else {
// disk access - uses FAT-table
tmp = (fatsect*BLOCK_SIZE) + fatpos*3;
memcpy(DiskFAT+tmp, FatEntry,3);
return(OK);
}
}
//////////////////////
// Convert MacFormat
// ===================
// - Convert really _stupid_ 'Mac'-format (ie. every '0x0a' is replaced by '0x0d0a')..
// Why this even exists !?!?
int ConvertMacFormat(int *in, char *in_file)
{
int out;
//int c;
unsigned int Hdr,i,prev;
char temp_file[FILENAME_MAX];
unsigned char *mem_pointer;
struct stat stat_buf;
lseek(*in,(long) 0,SEEK_SET);
read(*in,&Hdr,4);
lseek(*in,(long) 0,SEEK_SET);
Hdr = Hdr & 0x00FFFFFF;
if(Hdr == 0x0a0d0d) {
mkstemp(temp_file);
if((out =open(temp_file, O_RDWR | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",temp_file));
}
unlink(temp_file);
if(stat(in_file,&stat_buf) != 0) {
EEXIT((stderr,"ERROR: Can't get the filesize!!\n"));
}
mem_pointer=malloc(stat_buf.st_size);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
read(*in,mem_pointer, stat_buf.st_size);
// Find '0x0a' and copy fragments to file without proceeding '0x0d'
prev = 0;
for(i=0; i<stat_buf.st_size; i++) {
if(mem_pointer[i] == 0x0a) {
write(out,mem_pointer+prev,i - prev -1);
prev = i;
}
}
// if '0x0a' is last byte it has to write out separately..
// Otherwise write whats left...
if((i-1) != prev) {
write(out,mem_pointer+prev,i - prev);
} else {
write(out,mem_pointer+prev,1);
}
free(mem_pointer);
// Close orginal and give pointer to converted file
close(*in);
*in=out;
return(OK);
} else {
return(ERR);
}
}
//////////////////////
// ConvertToImageFile
int ConvertToImage(char in_file[FILENAME_MAX], char out_file[FILENAME_MAX])
{
int in, out;
struct stat stat_buf;
unsigned int i, j, skip_start, skip_size, num_of_tags, num_of_blks, img_length, img_offset;
unsigned char buffer[BLOCK_SIZE], Data[BLOCK_SIZE], *mem_pointer, *SkipTable;
char bits, *p;
mem_pointer=NULL;
if((in=open(in_file, O_RDONLY | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
}
umask(0777);
printf("outfile %s ConvertToImage\n\n\n\n\n", out_file); fflush(stdout);
if((out=open(out_file, O_EXCL| O_RDWR | O_BINARY, 0777 )) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file %d '%s'.\n",errno, out_file));
}
if((p= (char *) rindex(in_file,'.')) != NULL) {
p++;
printf("Extension: %s\n",p);
if(strcasecmp(p,"gkh") == 0) {
printf("GKH-file found\n");
//// GKH ////
if(stat(in_file,&stat_buf) != 0) {
EEXIT((stderr,"ERROR: Can't get the filesize!!\n"));
}
lseek(in,(long) 0, SEEK_SET);
read(in,Data,8);
if(Data[4] != 'I') {
EEXIT((stderr,"ERROR: GKH file in Motorola format is not supported!!\n"));
}
//num_of_tags = (Data[6] & 0x000000ff) + (Data[7] & 0x000000ff);
num_of_tags = (unsigned int) (*((unsigned int *) (Data+6)) & 0x0000ffff);
printf("num_of_tags= %d\n",num_of_tags);
for(i=0; i<num_of_tags; i++) {
read(in,Data,10);
// DISKINFO-tag
if(*Data == 0x0a) {
num_of_blks = (unsigned int) ((*((unsigned int *) (Data+2)) & 0x0000ffff) *
(*((unsigned int *) (Data+4)) & 0x0000ffff) *
(*((unsigned int *) (Data+6)) & 0x0000ffff));
printf("num_of_blks = %d\n", num_of_blks);
}
// DISKINFO-tag
if(*Data == 0x0b) {
img_length = (unsigned int) *((unsigned int *)(Data+2));
img_offset = (unsigned int) *((unsigned int *)(Data+6));
printf("img_length = %d\n", img_length);
printf("img_offset = %d\n", img_offset);
}
}
// Skip the 58-byte header
lseek(in,(long) img_offset, SEEK_SET);
// Do copy...
for(i=0; i<num_of_blks;i++) {
read(in,Data,BLOCK_SIZE);
write(out,Data,BLOCK_SIZE);
}
// Get INFO after image
// -- uncomment if INFO needed
/*
if(!feof(in)) {
printf("\nInfo included in GKH file: \n");
bits=fgetc(in);
while (feof(in) == 0) {
printf("%c",bits);
bits=fgetc(in);
}
printf("\n");
}
*/
} else if ((strcasecmp(p,"ede") == 0) || (strcasecmp(p,"eda") == 0)) {
//// EDE / EDA /////
if (strcasecmp(p,"ede") == 0) {
skip_start= EDE_SKIP_START;
skip_size = EDE_SKIP_SIZE;
} else {
skip_start= EDA_SKIP_START;
skip_size = EDA_SKIP_SIZE;
}
// Write 'empty'-buffer
for(i=0; i<BLOCK_SIZE;i=i+2) {
buffer[i ]=0x6D;
buffer[i+1]=0xB6;
}
// Check and convert if 'Mac'-format :-P is found
if(ConvertMacFormat(&in, in_file) == OK) {
printf("Warning: Macintosh generated EDx file found!\n");
}
mem_pointer=malloc(BLOCK_SIZE);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
SkipTable = mem_pointer + skip_start;
// Read Ede/Eda skip Table
lseek(in, (long) 0, SEEK_SET);
read(in,mem_pointer,BLOCK_SIZE);
lseek(in, BLOCK_SIZE, SEEK_SET);
for(i=0; i<skip_size;i++) {
bits= SkipTable[i];
for(j=0;j<8;j++) {
if(bits < 0) {
write(out,buffer,BLOCK_SIZE);
} else {
read(in,Data,BLOCK_SIZE);
write(out,Data,BLOCK_SIZE);
}
bits=bits << 1;
} // for j
} // for i
} else {
// other extension - lets guess its raw-image
printf("No conversion!\n");
free(mem_pointer);
close(in);close(out);
return(ERR);
}
} else {
// Can't get file type
printf("No conversion!\n");
free(mem_pointer);
close(in); close(out);
return(ERR);
}
printf("conversion done!\n");
free(mem_pointer);
close(in); close(out);
return(OK);
}
//////////////////////
// ConvertFromImage
int ConvertFromImage (char in_file[FILENAME_MAX], char out_file[FILENAME_MAX], char type)
{
int in,out;
unsigned char bits, *SkipTable, *mem_pointer, edx_id;
char edx_label[12];
unsigned int skip_size, skip_start,block, i,j;
unsigned char Data[BLOCK_SIZE];
edx_id = 0; skip_start = 0; skip_size = 0;
switch (type)
{
case EDE_TYPE:
skip_start= EDE_SKIP_START;
skip_size = EDE_SKIP_SIZE;
edx_id = EDE_ID;
strcpy(edx_label, EDE_LABEL);
break;
case EDA_TYPE:
skip_start= EDA_SKIP_START;
skip_size = EDA_SKIP_SIZE;
edx_id = EDA_ID;
strcpy(edx_label, EDA_LABEL);
break;
case GKH_TYPE:
EEXIT((stderr,"ERROR: GKH-output not supported yet!\n"));
default:
EEXIT((stderr,"ERROR: Unsupported conversion!\n"));
}
printf("RAW -> EDx conversion!!\n");
if((in=open(in_file, O_RDONLY | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.",in_file));
}
umask(0777);
printf("outfile %s\n ******************************", out_file);
if((out=open(out_file, O_EXCL| O_RDWR | O_BINARY, 0777 )) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file %d '%s'.",errno, out_file));
}
mem_pointer = malloc(BLOCK_SIZE);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
SkipTable=mem_pointer+skip_start;
// Construct EDx header
// CR & LF
mem_pointer[0]=0x0D;
mem_pointer[1]=0x0A;
// Spaces trough 0x02 - 0x4D
for(i=0x02; i<0x4E;i++) {
mem_pointer[i] = 0x20;
}
// Write EDE label
strncpy((char *) (mem_pointer+2), edx_label, 11);
// CR & LF
mem_pointer[0x4E]=0x0D;
mem_pointer[0x4F]=0x0A;
// Spaces trough 0x50 - skip_start
for(i=0x50; i<skip_start;i++) {
mem_pointer[i] = 0x20;
}
// CR & LF
mem_pointer[skip_start-3]=0x0D;
mem_pointer[skip_start-2]=0x0A;
mem_pointer[skip_start-1]=0x1A;
// Disktype ID
mem_pointer[BLOCK_SIZE-1] = edx_id;
// Write Header
write(out,mem_pointer,BLOCK_SIZE);
// Generate SkipTable
block=0;
for(i=0; i<skip_size ; i++) {
bits=0;
for(j=0; j<8 ; j++) {
bits=bits << 1;
if(GetFatEntry('f',NULL,in,block) == 0) {
bits=bits | 0x01;
} else {
lseek(in, block * BLOCK_SIZE, SEEK_SET);
read(in,Data, BLOCK_SIZE);
write(out,Data,BLOCK_SIZE);
}
block++;
}
SkipTable[i]=bits;
}
// Write last EOF-marker
//fputc(0x1A,out);
Data[0]=0x1A;
write(out,Data,1);
lseek(out, skip_start, SEEK_SET);
write(out,SkipTable,skip_size);
return(OK);
}
///////////////
// IsEFE
int IsEFE(char in_file[FILENAME_MAX])
{
char *p;
if((p=rindex(in_file,'.')) != NULL) {
// Extension found!
p++;
printf("Extension: %s\n",p);
if((strcasecmp(p,"efe") == 0) || (strcasecmp(p,"efa") == 0) ) {
printf("EFE-file found\n");
return(OK);
}
}
return(ERR);
}
///////////////////
// GetImageType
int GetImageType(char in_file[FILENAME_MAX], char *image_type)
{
char *p;
struct stat stat_buf;
if((p=rindex(in_file,'.')) != NULL) {
// Extension found!
p++;
printf("Extension: %s\n",p);
if(strcasecmp(p,"gkh") == 0) {
printf("GKH-file found\n");
*image_type=GKH_TYPE;
return(OK);
} else if(strcasecmp(p,"ede") == 0) {
printf("EDE-file found\n");
*image_type=EDE_TYPE;
return(OK);
} else if(strcasecmp(p,"eda") == 0) {
printf("EDA-file found\n");
*image_type=EDA_TYPE;
return(OK);
}
}
// No or unknown extension - check if known raw-image
// Uncomment for header-check when raw-image expected
/*
if((in=fopen(in_file, "rb"))== NULL) {
EEXIT((stderr, "ERROR: Couldn't open file '%s'.", in_file));
}
fseek(in, 512,0);
fread(&Hdr,sizeof(unsigned long), 1,in);
printf("hdr: %lx \n", Hdr);
*/
if(stat(in_file,&stat_buf) != 0) {
//fprintf(stderr,"\n(line: %d) ERROR: Can't get the filesize!!\n", __LINE__);
return(ERR);
}
printf("filesize: %ld\n",stat_buf.st_size);
if(stat_buf.st_size == EPS_IMAGE_SIZE) {
printf("EPS-file found\n");
*image_type = EPS_TYPE;
return(OK);
} else if(stat_buf.st_size == ASR_IMAGE_SIZE) {
printf("ASR-file found\n");
*image_type = ASR_TYPE;
return(OK);
} else {
//fprintf(stderr,"\nWarning! Not a known file format. Might be an HD-image or SCSI-device! \n\n");
*image_type = OTHER_TYPE;
return(OK);
}
}
////////////////////
// GetTHS
void GetTHS(unsigned int block, unsigned int num_of_sect,
unsigned int *track, unsigned int *head, unsigned int *sector)
{
*track = block / (2 * num_of_sect);
*head = (block - (*track * 2 * num_of_sect)) / num_of_sect;
*sector = block - (*track * 2 * num_of_sect) - (*head * num_of_sect);
}
////////////////////
// OpenFloppy
FD_HANDLE OpenFloppy (int drive)
{
FD_HANDLE fd;
printf("unsed openfloppy");
return fd;
}
////////////////////
// CloseFloppy
void CloseFloppy(FD_HANDLE fd)
{
printf("unsed closefloppy");
}
//////////////////////////////////////
// Set FD geometry. 'a'=ASR, 'e'=EPS
void FD_SetGeometry(FD_HANDLE fd, char disk_type)
{
printf("unsed FD_SetGeometry");
}
// Calibrate FD
void FD_Calibrate(int fd)
{
printf("unsed FD_Calibrate");
}
///////////////////////
// Seek the FD track
void FD_Seek(FD_HANDLE fd, int track)
{
printf("unsed FD_Seek");
}
////////////////////////////
// FD_Raw Read/Write Track
// (read: rw=1, write: rw=2)
int FD_RawRW_DiskTrack(FD_HANDLE fd, char disk_type, int track, int head, char *buffer, int rw)
{
printf("unsed FD_RawRW_DiskTrack");
return 0;
}
////////////////////////////
// FD_Raw Read/Write Blocks
// (read: rw=1, write: rw=2)
int FD_RawRW_DiskSectors(FD_HANDLE fd, char disk_type, int track, int head,
int sector, int num_of_sectors, char *buffer, int rw)
{
printf("unsed FD_RawRW_DiskSectors");
return 0;
}
////////////////////
// Format DiskTrack
int FD_Format_DiskTrack(FD_HANDLE fd, int track, int head, int nsect, int rate, int skew)
{
printf("unsed FD_Format_DiskTrack");
return 0;
}
////////////////
// MakeID_Block
void MakeID_Block(unsigned char *buffer, char *label, unsigned int tracks,
unsigned int nsect, unsigned int total_blks)
{
int i;
for(i=0; i<BLOCK_SIZE;i++) {
buffer[i]=0;
}
// Device type
//buffer[0] = 0x00;
// Rem. Media device Type
buffer[1] = 0x80;
// Std. vers. #
buffer[2] = 0x01;
// SCSI
//buffer[3] = 0x00;
// Nsect
buffer[4] = 0x00; buffer[5] = (unsigned char) nsect;
// Heads
buffer[6] = 0x00; buffer[7] = 0x02;
// Tracks
buffer[8] = 0x00; buffer[9] = (unsigned char) tracks;
// Bytes per Block - 512
buffer[10] = 0x00; buffer[11] = 0x00; buffer[12] = 0x02; buffer[13] = 0x00;
// Total Blocks
buffer[14] = (total_blks >> 24) & 0x000000ff; // MSB
buffer[15] = (total_blks >> 16) & 0x000000ff;
buffer[16] = (total_blks >> 8) & 0x000000ff;
buffer[17] = total_blks & 0x000000ff; // LSB
// SCSI Medium Type
buffer[18] = 0x1e;
// SCSI Density Code
buffer[19] = 0x02;
// reserved (20-29)
// Disk Label
if(label != NULL) {
for(i=0;i<7;i++) {
buffer[31+i] = label[i];
}
buffer[30] = 0xff;
}
// ID
buffer[38] = 'I'; buffer[39] = 'D';
}
/////////////////
// MakeOS_Block
void MakeOS_Block(unsigned char *buffer, unsigned int free_blks)
{
int i;
for(i=0; i<BLOCK_SIZE;i++) {
buffer[i]=0;
}
// Free Blocks
buffer[0] = (free_blks >> 24) & 0x000000ff; // MSB
buffer[1] = (free_blks >> 16) & 0x000000ff;
buffer[2] = (free_blks >> 8) & 0x000000ff;
buffer[3] = free_blks & 0x000000ff; // LSB
// ID
buffer[28] = 'O';
buffer[29] = 'S';
}
/////////////////
// MakeDR_Block
void MakeDR_Block(unsigned char *buffer, int write_id)
{
int i;
for(i=0; i<BLOCK_SIZE;i++) {
buffer[i]=0;
}
if(write_id == 1) {
buffer[510]='D';
buffer[511]='R';
}
}
//////////////////////
// Format Disk
void FD_Format_Disk(char disk_type, int nsect, int rate, char* disk_label)
{
FD_HANDLE fd;
int track,head,free_blks,fat_blks,i,j,skew,head_skew,track_skew;
unsigned char buffer[BLOCK_SIZE*40];
char str[81],tmp;
// Init the skew factory for the disk
if(disk_type=='e') {
track_skew = nsect-2;
head_skew = nsect-1;
skew = -track_skew;
} else {
track_skew = nsect-3;
head_skew = nsect-2;
skew = -track_skew;
}
// Calc disk parameters
fat_blks = nsect*2*80 / 170 +1;
free_blks = nsect*2*80 - (5 + fat_blks);
//Open FD
fd = OpenFloppy(0);
FD_SetGeometry(fd,disk_type);
printf("1 10 20 30 40 50 60 70 80\n");
sprintf(str,"|---+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|");
for(track=0; track<80; track++) {
//Shift sectors (track skew)
skew=skew+track_skew;
for(head=0; head<2; head++) {
if(head==0) {
tmp = str[track];
str[track]='\\';
} else {
// Shift sectors (head skew)
skew=skew+head_skew;
str[track]='/';
}
printf("\r%s",str);
fflush(stdout);
if((FD_Format_DiskTrack(fd,track,head,nsect,rate,skew)) == ERR) {
exit(ERR);
}
} //for head
if(tmp == '|') str[track]=tmp; else str[track]='#';
}// for track
printf("\r%s",str);
fflush(stdout);
printf("\n\nWriting System Block..\n");
// TODO: Get the FD status so we don't have to wait
sleep(1);
// Write System-Blocks
for(i=0; i<BLOCK_SIZE*40;i++) {
buffer[i]=0;
}
// ID-Block
MakeID_Block(buffer+BLOCK_SIZE,disk_label,80,nsect,2*80*nsect);
// OS-Block
MakeOS_Block(buffer+BLOCK_SIZE*2, free_blks);
// Write Dir-ID (to second Dir-Block)
buffer[BLOCK_SIZE*4 + 510] = 'D';
buffer[BLOCK_SIZE*4 + 511] = 'R';
// FAT-Blocks
for(i=0; i<fat_blks; i++) {
if(i==0) {
for(j=0; j<(fat_blks+5); j++) {
buffer[BLOCK_SIZE * 5 + 3*j + 2] = 1;
}
}
buffer[BLOCK_SIZE * (5+i) + 510] = 'F';
buffer[BLOCK_SIZE * (5+i) + 511] = 'B';
}
if(FD_RawRW_DiskTrack(fd,disk_type,0,0,buffer,WRITE) == ERR) {
EEXIT((stderr,"ERROR: Couldn't write SystemData to disk!!\n\n"));
}
if(FD_RawRW_DiskTrack(fd,disk_type,0,1,buffer+(nsect*BLOCK_SIZE),WRITE) == ERR) {
EEXIT((stderr,"ERROR: Couldn't write SystemData to disk!!\n\n"));
}
printf("Operation completed succesfully!\n\n");
CloseFloppy(fd);
}
///////////////////////////////////////////////////////////
// Check which type of disk is inserted (EPS=DD or ASR=HD)
int FD_GetDiskType(char *disk_type, int *nsect, int *trk_size)
{
FD_HANDLE fd;
char buffer[20*512];
*disk_type='n';
//Open FD
fd=OpenFloppy(0);
// EPS-Disk !? (DD)
FD_SetGeometry(fd,'e');
if((FD_RawRW_DiskTrack(fd,'e',0,0,buffer,READ) )== ERR) {
//.. OR ASR-Disk !? (HD)
FD_SetGeometry(fd,'a');
if((FD_RawRW_DiskTrack(fd,'a',0,0,buffer,READ) )== ERR) {
// NEITHER :(
return(ERR);
} else { // ASR
printf("\nASR-Disk detected..\n");
*disk_type = 'a';
*nsect=20;
*trk_size = 20* 512;
}
} else { // EPS
printf("\nEPS-Disk detected..\n");
*disk_type = 'e';
*nsect=10;
*trk_size = 10* 512;
}
CloseFloppy(fd);
return(OK);
}
//////////////////////////
// Read/Write the Disk
void FD_RW_Disk(char in_file[FILENAME_MAX], int rw_disk)
{
int file;
FD_HANDLE fd;
int track,head,nsect,trk_size,convert,idx, errors;
char disk_type, image_type;
char buffer[512 * 20],str[81],tmp, filename[FILENAME_MAX];
char mark[5] = {'\\','/','#','E','E'};
char errors_text[20000];
errors=0; idx=0; errors_text[0]='\0';
// Check image file
if((GetImageType(in_file, &image_type) == ERR) && (rw_disk == WRITE)) {
EEXIT((stderr,"ERROR: NOT a valid image!!\n\n"));
}
// Check disk
if(FD_GetDiskType(&disk_type, &nsect, &trk_size) == ERR) {
EEXIT((stderr,"ERROR: NOT an Ensoniq Disk.\n\n"));
}
// Check if disk and file types match
if(disk_type == EPS_TYPE) {
strcpy(str,"EPS-DISK");
if(image_type == EDA_TYPE) {
EEXIT((stderr,"ERROR: Don't use EPS disks with EDA files! Replace extension 'eda' to 'ede'.\n"));
}
} else {
strcpy(str,"ASR-DISK");
if(image_type == EDE_TYPE) {
EEXIT((stderr,"ERROR: Don't use ASR disks with EDE files! Replace extension 'ede' to 'eda'.\n"));
}
}
//Open FD
fd=OpenFloppy(0);
FD_SetGeometry(fd,disk_type);
// If file type is other than image, conversion is needed
if((image_type == GKH_TYPE) && (rw_disk == READ)) {
EEXIT((stderr,"Sorry! Reading disk to GKH file is not yet supported!.\n"));
}
if((image_type == EDE_TYPE) || (image_type == EDA_TYPE) || (image_type == GKH_TYPE)) {
// Generate tmp-file and bind the clean-up for it
//tmpnam(tmp_file);
if(mkstemp(tmp_file) == -1) {
perror("mkstemp");
exit(ERR);
}
atexit(CleanTmpFile);
convert = 1;
} else {
convert = 0;
strcpy(filename,in_file);
}
// Open image-file
if(rw_disk == READ) {
if(convert) strcpy(filename,tmp_file);
if((file = open(filename,O_RDWR | O_CREAT | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",filename));
}
printf("Reading %s to file '%s'..\n\n",str,in_file);
} else {
// Check if conversion is needed
if(convert) {
if(ConvertToImage(in_file,tmp_file) == OK) {
printf("CONVERSION DONE!!!\n");
//repalace in_file to converted image
strcpy(filename,tmp_file);
} else {
EEXIT((stderr,"ERROR: Something wrong with the image file!!\n"));
}
}
file = open(filename,O_RDONLY | O_BINARY);
printf("Writing %s from file '%s'..\n\n",str,in_file);
}
printf("1 10 20 30 40 50 60 70 80\n");
sprintf(str,"|---+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|");
for(track=0; track<80; track++) {
//FD_Seek(fd,track);
for(head=0; head<2; head++) {
tmp = str[track];
str[track]=mark[idx];
printf("\r%s",str);
fflush(stdout);
if(rw_disk == WRITE) {
read(file,buffer,trk_size);
}
{
int retry_cnt=0;
retry:
if(FD_RawRW_DiskTrack(fd,disk_type,track,head,buffer,rw_disk) == ERR) {
// Error: 'E'
idx=2;
//Show retry count
str[track]='0'+retry_cnt;
printf("\r%s",str);
fflush(stdout);
retry_cnt++;
if (retry_cnt <= 9 ) goto retry; // Yes, I know.. The Goto is a "bad programming"
//Error text & count
sprintf(errors_text+strlen(errors_text)," ERROR: track=%d, head=%d\n",track,head);
errors++;
}
}
if(rw_disk == READ) {
write(file,buffer,trk_size);
}
idx++;
} //for head
if((mark[idx] != 'E') && ((((track+1) % 10) == 0) || (track == 0))) str[track]='|';
else str[track]=mark[idx];
idx=0;
}// for track
printf("\r%s",str);
fflush(stdout);
if(convert && rw_disk==READ) {
ConvertFromImage(filename,in_file,image_type);
}
if(errors > 0) {
printf("\n\nWarning: %d error(s) found!\n",errors);
printf("\n%s\n",errors_text);
} else {
printf("\n\nOperation completed succesfully!\n\n");
}
CloseFloppy(fd);
}
/////////////////////////////////////////////////////////////////
// ReadBlocks
// ----------
// media_type : 'file'-access('f') or disk-access('e','a')
// fd : device (dev/fd0) file descriptor (depends on media_type if needed!)
// file : file descriptor (depends on media_type if needed!)
// start_block : First block to read
// length : How many blocks to read
// buffer : Where to put the data
int ReadBlocks(char media_type, FD_HANDLE fd, int file, unsigned int start_block,
unsigned int length, unsigned char *buffer)
{
unsigned int sector,head,track;
unsigned int end_sector, end_head, end_track;
unsigned int end_block, cur_block,nsect = 0;
unsigned char tmp_buffer[BLOCK_SIZE*20];
switch (media_type)
{
case 'f':
if(lseek(file, start_block * BLOCK_SIZE, SEEK_SET) == -1) {
printf("ERROR in seek\n");
exit(ERR);
}
if(read(file,buffer, BLOCK_SIZE*length) == 0) {
printf("ERROR in read\n");
exit(ERR);
}
return(OK);
case 'e':
nsect=10;
break;
case 'a':
nsect=20;
break;
}
GetTHS(start_block,nsect,&track,&head,&sector);
end_block = start_block + length -1;
GetTHS(end_block,nsect,&end_track,&end_head,&end_sector);
FD_RawRW_DiskTrack(fd,media_type,track,head,tmp_buffer,READ);
cur_block = start_block;
while(cur_block <= end_block) {
memcpy(buffer,tmp_buffer+(sector*BLOCK_SIZE), BLOCK_SIZE);
buffer=buffer+BLOCK_SIZE;
cur_block++;
sector++;
printf("\r Reading from disk: %-4d of %-4d (blocks) .. ", cur_block-start_block, end_block-start_block+1);
//fflush(stdout);
if(sector>(nsect-1) && cur_block <= end_block ) {
//Load next track
GetTHS(cur_block,nsect,&track,&head,&sector);
FD_RawRW_DiskTrack(fd,media_type,track,head,tmp_buffer,READ);
sector=0;
}
}
printf("\r ");
//fflush(stdout);
return(OK);
}
/////////////////////////////////////////////////////////////////
// WriteBlocks
// ----------
// media_type : 'file'-access('f') or disk-access('e','a')
// fd : device (dev/fd0) file descriptor (depends on media_type if needed!)
// file : file descriptor (depends on media_type if needed!)
// start_block : First block to write
// length : How many blocks to write
// buffer : Where to get the data
int WriteBlocks(char media_type, FD_HANDLE fd, int file, unsigned int start_block,
unsigned int length, unsigned char *buffer)
{
int sector,head,track;
int end_sector, end_head, end_track;
unsigned int end_block, cur_block,nsect = 0, num_of_sectors, start_sector, tmp;
unsigned char tmp_buffer[BLOCK_SIZE*20];
switch (media_type)
{
case 'f':
lseek(file, start_block * BLOCK_SIZE, SEEK_SET);
write(file,buffer, BLOCK_SIZE*length);
return(OK);
case 'e':
nsect=10;
break;
case 'a':
nsect=20;
break;
}
GetTHS(start_block,nsect,&track,&head,&sector);
end_block = start_block + length -1;
GetTHS(end_block,nsect,&end_track,&end_head,&end_sector);
cur_block = start_block;
start_sector = sector;
do {
memcpy(tmp_buffer+(sector*BLOCK_SIZE),buffer, BLOCK_SIZE);
buffer=buffer+BLOCK_SIZE;
if(sector >= (nsect-1) || cur_block >= end_block ) {
//Write blocks to disk
num_of_sectors = sector - start_sector+1;
GetTHS(cur_block,nsect,&track,&head,&tmp);
FD_RawRW_DiskSectors(fd,media_type,track,head,start_sector, num_of_sectors, \
tmp_buffer+(start_sector*BLOCK_SIZE),WRITE);
sector=0;
start_sector=0;
} else {
sector++;
}
cur_block++;
printf("\r Writing to disk: %-4d of %-4d (blocks) .. ", cur_block-start_block, end_block-start_block+1);
fflush(stdout);
} while(cur_block <= end_block);
printf("\r ");
fflush(stdout);
return(OK);
}
//////////////////////////////////////////////
// Load Dir entry to Efe-array - use FAT-table
void LoadDirBlocks(char media_type, FD_HANDLE fd, unsigned char *DiskFAT, int file,
unsigned long start_blk, int cont, unsigned char Efe[][EFE_SIZE])
{
unsigned char Dir[DIR_BLOCKS*BLOCK_SIZE];
int i,j;
// Get DirBlocks
// First dir-block - Guess the block are contiguous, so read 2 blocks
ReadBlocks(media_type,fd,file,start_blk,2,Dir);
//.. and second, if needed (ie. not contiguous..)
if(cont != 2) {
ReadBlocks(media_type,fd,file,GetFatEntry(media_type,DiskFAT,file,start_blk),1,Dir+BLOCK_SIZE);
}
// Scan Directory
for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
for(j=0; j < EFE_SIZE ; j++) {
Efe[i][j]=Dir[i * EFE_SIZE+j];
}
}
}
////////////////////////////////////////////////////
// FormatMedia
// -----------
// -Format (and create if needed) imagefile/device
//
int FormatMedia(char **argv, int argc, int optind, char format_arg, char *disk_label)
{
int file;
long long i,j,k,image_size, total_blks, free_blks, fat_blks,fat_count;
long long partial_blks, rest_blks;
unsigned char buffer[BLOCK_SIZE], nsect, tracks;
image_size=0;
switch(format_arg)
{
case 'a':
// ASR Disk
printf("\nFormatting ASR-DISK.. \n\n");
FD_Format_Disk('a',20,0,disk_label);
return(OK);
// ASR Disk
case 'e':
printf("\nFormatting EPS-DISK.. \n\n");
FD_Format_Disk('e',10,2,disk_label);
return(OK);
case 'i':
// IMAGEFILE/DEVICE
//Default values for image/scsi (ie. "don't care")
// Exception: for EPS/ASR _DISK_ images these values
// _has_ to be set correctly in the ID Block
// or else you have a disk that _instantly_
// reboots the keyboard when accessed!
// If You dare, test it yourself.. :-)
nsect=0;
tracks=0;
// check if file argument exists
if(argv[optind] == NULL) {
ShowUsage();
exit(ERR);
}
if((file=open(argv[optind],O_RDWR | O_BINARY)) != -1) {
//File exists.. get size
if((image_size=lseek(file,0,SEEK_END)) == -1) {
perror("lseek");
exit(ERR);
}
if((image_size % BLOCK_SIZE) != 0) {
printf("Image size have to be multiple of %d!\n",BLOCK_SIZE);
exit(ERR);
}
if(image_size == EPS_IMAGE_SIZE) {
//Assume EPS Disk image - see above for reason..
tracks=80;
nsect=10;
}
if(image_size == ASR_IMAGE_SIZE) {
//Assume ASR Disk image - see above for reason..
tracks=80;
nsect=20;
}
total_blks=image_size/BLOCK_SIZE;
} else {
// File DOESN'T exists..
// Check that file size is defined
if(argv[optind+1] == NULL) {
printf("No filesize defined!\n\n");
exit(ERR);
} else {
// Check that given size is correctly formatted
if((strcasecmp(argv[optind+1],"eps"))==0) {
//eps disk image
// Set the correct values for nsect and tracks (see above)
tracks=80;
nsect=10;
image_size=EPS_IMAGE_SIZE;
} else if ((strcasecmp(argv[optind+1],"asr"))==0) {
//asr disk image
// Set the correct values for nsect and tracks (see above)
tracks=80;
nsect=20;
image_size=ASR_IMAGE_SIZE;
} else {
// other
image_size=atol(argv[optind+1]);
if(image_size == 0) {
printf("No valid filesize!\n\n");
exit(ERR);
}
// Check if 'M' or 'K' suffix used
switch(argv[optind+1][strlen(argv[optind+1])-1])
{
case 'm':
case 'M':
image_size=image_size*1024;
case 'k':
case 'K':
image_size=image_size*1024;
}
}
}
// Check the validity of the given filesize ie. that is multiple of block size
if((image_size % BLOCK_SIZE) != 0) {
printf("Image size have to be multiple of %d!\n",BLOCK_SIZE);
exit(ERR);
}
total_blks=image_size/BLOCK_SIZE;
// create file
file = open( argv[optind], O_RDWR | O_CREAT | O_BINARY, 0600);
// Make empty file
// 1st clear the buffer
for(k=0; k<BLOCK_SIZE;k++) {
buffer[k]=0;
}
//..create
partial_blks = total_blks/100;
rest_blks = total_blks % 100;
for(j=0;j<100;j++) {
printf("\rCreating image file... %d%% completed", (int) j);
fflush(stdout);
for(i=0; i< partial_blks;i++) {
write(file,buffer,BLOCK_SIZE);
}
}
for(i=0;i<rest_blks;i++) {
write(file,buffer,BLOCK_SIZE);
}
printf("\rCreating image file... OK! \n");
fflush(stdout);
}
// Calc num of needed FAT-Blocks
printf("\rWriting filesystem....");
fflush(stdout);
fat_blks=total_blks / 170;
if((total_blks % 170) != 0)
fat_blks++;
free_blks=total_blks - (fat_blks+5);
//Write "not used" (first) block with added info
lseek(file,0,SEEK_SET);
for(i=0;i<BLOCK_SIZE;i++) buffer[i]=0;
sprintf(buffer,"m%s",FIRST_BLOCK_MESSAGE);
write(file,buffer,BLOCK_SIZE);
//Write ID-Block
lseek(file,BLOCK_SIZE*ID_BLOCK,SEEK_SET);
MakeID_Block(buffer,disk_label,tracks,nsect,total_blks);
write(file,buffer,BLOCK_SIZE);
//Write OS-Block
lseek(file,BLOCK_SIZE*OS_BLOCK,SEEK_SET);
MakeOS_Block(buffer,free_blks);
write(file,buffer,BLOCK_SIZE);
//Write Dir-Blocks
lseek(file,BLOCK_SIZE*DIR_START_BLOCK,SEEK_SET);
MakeDR_Block(buffer,0);
write(file,buffer,BLOCK_SIZE);
lseek(file,BLOCK_SIZE*DIR_END_BLOCK,SEEK_SET);
MakeDR_Block(buffer,1);
write(file,buffer,BLOCK_SIZE);
//Write FAT-Blocks
fat_count=fat_blks+5;
//for(i=0; i<BLOCK_SIZE;i++) {
// buffer[i]=0;
//}
buffer[510] = 'F';
buffer[511] = 'B';
for(i=0; i<fat_blks; i++) {
// Clear buffer needed: once at start and once after all "used block" marked
if(fat_count >= 0) {
for(k=0; k<BLOCK_SIZE-2;k++) {
buffer[k]=0;
}
if(fat_count==0)
fat_count--;
}
if(fat_count > 0) {
for(j=0; j<510; j=j+3) {
buffer[j] = 0;
buffer[j+1] = 0;
buffer[j+2] = 1;
fat_count--;
if(fat_count == 0) {
break;
}
}
}
lseek(file,BLOCK_SIZE*(i+5),SEEK_SET);
if( write(file,buffer,BLOCK_SIZE) <= 0)
perror("write:");
}
printf("\rWriting filesystem.... OK!\n\n");
fflush(stdout);
close(file);
} // case
return(OK);
}
////////////////////////////////////////////////
// Save Dir entry from Efe-array - use FAT-table
void SaveDirBlocks(char media_type, FD_HANDLE fd, unsigned char *DiskFAT, int file,
unsigned long start_blk, int cont, unsigned char Efe[][EFE_SIZE])
{
unsigned char Dir[DIR_BLOCKS*BLOCK_SIZE];
int i,j;
// Put Directory
for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
for(j=0; j < EFE_SIZE ; j++) {
Dir[i * EFE_SIZE+j]=Efe[i][j];
}
}
// .. and tail (ie. '00000000' and 'DR')
for(i=10; i<2; i--) {
Dir[DIR_BLOCKS*BLOCK_SIZE - i] = 0;
}
Dir[DIR_BLOCKS*BLOCK_SIZE - 2] = 'D';
Dir[DIR_BLOCKS*BLOCK_SIZE - 1] = 'R';
// Put DirBlocks
if(cont == 2) {
// If contiguous, write all in one
WriteBlocks(media_type,fd,file,start_blk,2,Dir);
} else {
// .. and if not, do it separately
WriteBlocks(media_type,fd,file,start_blk,1,Dir);
WriteBlocks(media_type,fd,file,GetFatEntry(media_type,DiskFAT,file,start_blk),1,Dir+BLOCK_SIZE);
}
}
/////////////////////////////
// GetEFEs
int GetEFEs(char media_type, FD_HANDLE fd, int in, unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
char *process_efe, unsigned char *DiskFAT)
{
int out;
unsigned int i,j,k, size, cont, start, fatval, bp;
unsigned char type, Header[BLOCK_SIZE], *mem_pointer;
char name[13],dosname[64],tmp_name[64];
unsigned char Data[BLOCK_SIZE];
char type_text[8];
// Process Efe's list
for(j=0;j<MAX_NUM_OF_DIR_ENTRIES;j++) {
// Check if current efe has to be processed
if(process_efe[j] == 0) continue;
// Get info
if((type=Efe[j][1]) == 0) continue;
size =(unsigned int) ((Efe[j][14] << 8) + Efe[j][15]);
cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
start=(unsigned long) ((Efe[j][18] << 24) + (Efe[j][19] << 16)
+(Efe[j][20] <<8 ) + Efe[j][21]);
//Name
for(k=0;k<12;k++) {
name[k]=Efe[j][k+2];
}
name[12]=0;
// Name to DosName
DosName(dosname,name);
//Add type (and multifile) prefix to filename
if(Efe[j][22] != 0) {
strcpy(type_text,EpsTypes[type]);
type_text[5]='\0';
sprintf(type_text,"%s%2d",type_text,Efe[j][22]);
sprintf(tmp_name,"[%s] %s",type_text,dosname);
} else {
sprintf(tmp_name,"[%s] %s",EpsTypes[type],dosname);
}
sprintf(dosname,"%s",tmp_name);
//Add index prefix to filename
sprintf(tmp_name,"[%02d]%s",j,dosname);
sprintf(dosname,"%s",tmp_name);
// Write EFE-Header
//Construct Header
Header[0] =0x0D;
Header[1] =0x0A;
strcpy(&Header[2],"Eps File: ");
strcpy(&Header[18],name);
strcpy(&Header[30],EpsTypes[type]);
strcpy(&Header[37]," ");
// CR, LF, EOF
Header[47]=0x0D; Header[48]=0x0A; Header[49]=0x1A;
Header[50]=Efe[j][1]; // Instrument
Header[51]=0;
Header[52]=Efe[j][14];
Header[53]=Efe[j][15];
Header[54]=Efe[j][16];
Header[55]=Efe[j][17];
Header[56]=Efe[j][20];
Header[57]=Efe[j][21];
Header[58]=Efe[j][22]; // MultiFile index
for(i=59;i<BLOCK_SIZE;i++) Header[i]=0;
if((out=open(dosname,O_RDWR | O_CREAT | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",dosname));
}
write(out,Header,BLOCK_SIZE);
printf("\rProcessing [%s]...",name);fflush(stdout);
// Copy contiguous blocks
if(media_type=='f') {
// FILE - ACCESS
for(i=0;i<cont;i++) {
ReadBlocks(media_type,fd,in,start+i,1,Data);
write(out,Data,BLOCK_SIZE);
}
} else {
// DISK - ACCESS - Can be copied in one big chunck (disk size is limited!)
mem_pointer=malloc(BLOCK_SIZE*cont);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
ReadBlocks(media_type,fd,in,start,cont,mem_pointer);
write(out,mem_pointer,BLOCK_SIZE*cont);
free(mem_pointer);
}
//Get rest of the blocks
bp=start+cont-1;
fatval=GetFatEntry(media_type,DiskFAT,in,bp);
if(fatval != 1) {
if(media_type == 'f') {
// FILE ACCESS
while(fatval !=1) {
ReadBlocks(media_type,fd,in,fatval,1,Data);
write(out,Data,BLOCK_SIZE);
bp=fatval;
fatval = GetFatEntry(media_type,DiskFAT,in,bp);
}
} else {
// DISK ACCESS
while(fatval != 1) {
// Find contigous blocks from FAT-table
cont=1;
start=fatval;
bp=fatval;
fatval=GetFatEntry(media_type,DiskFAT,in,start);
while(fatval == bp+1) {
bp=fatval;
fatval = GetFatEntry(media_type,DiskFAT,in,bp);
cont++;
}
// Copy contigous blocks
mem_pointer=malloc(BLOCK_SIZE*cont);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
ReadBlocks(media_type,fd,in,start,cont,mem_pointer);
write(out,mem_pointer,BLOCK_SIZE*cont);
free(mem_pointer);
} // while
} // else
} // if
printf("\r ");
close(out);
}
return(OK);
}
//////////////////////////////////////////////////////////////
// PutEFE
// ------
// - This function can be used for writing EFEs to disk/image
// from EFE-file or from memory. If memory is used, the
// pointer for efe header (MemDataHdr) and efe data (MemData)
// are needed!!
int PutEFE(
char *process_efe,
unsigned char start_idx,
unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
char media_type,
char image_type,
char *image_file,
char **efe_files,
int optind,
char *orig_image_name,
unsigned int dir_start,
unsigned int dir_cont,
unsigned int total_blks,
unsigned int *free_blks,
unsigned int fat_blks,
FD_HANDLE fd,
unsigned char *DiskFAT,
unsigned char *DiskHdr,
unsigned char *MemDataHdr,
unsigned char *MemData
)
{
int in, out;
char in_file[FILENAME_MAX];
unsigned int idx,i,j,blks,start;
unsigned char efe_name[13], EfeData[EFE_SIZE], buffer[4], efe_type, Data[BLOCK_SIZE];
unsigned char *mem_pointer;
unsigned int efe_start_block, efe_blks, first_free_block, first_cont_blks, prev_block;
unsigned int free_start, free_cnt, OS;
if((media_type == 'f') && (MemData == NULL)) {
// FILE ACCESS
if((out=open(image_file, O_RDWR | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open image file '%s'.\n",image_file));
}
// Skip image_file
optind++;
}
// PROCESS ALL EFEs
// KLUDGE!!!
while((MemData != NULL) || (efe_files[optind] != NULL)) {
// Starting at pos 'start_idx' !!
// (It's quite a unusual to put other that OS or SubDir to idx 0)
for(idx= start_idx; idx<MAX_NUM_OF_DIR_ENTRIES; idx++) {
if(Efe[idx][1] == 0) break;
}
process_efe[idx] = 1;
if(idx==MAX_NUM_OF_DIR_ENTRIES) {
printf("\r \r");fflush(stdout);
// Write SystemBlocks to disk and free mem
// so that efes so far will be saved..
WriteBlocks(media_type,fd,out,0,5+fat_blks,DiskHdr);
free(DiskHdr);
printf("ERROR: Directory full!\n");
//EEXIT((stderr,"ERROR: Directory full!\n"));
return(ERR);
}
if(MemData == NULL) {
//EFE from file
//=============
// Efe-file
if((in=open(efe_files[optind], O_RDONLY | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",efe_files[optind]));
}
strcpy(in_file,efe_files[optind]);
printf("input efe %s\n", in_file);
// Check and convert if 'Mac'-format :-P is found
if(ConvertMacFormat(&in, in_file) == OK) {
printf("Warning: Macintosh generated EFx file found!\n");
}
lseek(in, (long) 0x32, SEEK_SET);
read(in,EfeData, EFE_SIZE);
lseek(in, (long) 0x12, SEEK_SET);
read(in,efe_name,12);
efe_name[12]='\0';
efe_blks = (EfeData[2] << 8) + EfeData[3];
efe_type = EfeData[0];
// name
strcpy(&Efe[idx][2],efe_name);
// zero
Efe[idx][0] = 0;
// type
Efe[idx][1] = efe_type;
// size
Efe[idx][14] = EfeData[2];
Efe[idx][15] = EfeData[3];
// MultiFile index
Efe[idx][22] = EfeData[8];
// empty
Efe[idx][23] = 0; Efe[idx][24] = 0; Efe[idx][25] = 0;
// If efe is OS, get OS version
switch (efe_type)
{
case 1: // EPS OS
lseek(in, EPS_OS_POS, SEEK_SET);
read(in,&OS,4);
break;
case 27: // E16 OS
lseek(in, E16_OS_POS, SEEK_SET);
read(in,&OS,4);
break;
case 32: // ASR OS
lseek(in, ASR_OS_POS, SEEK_SET);
read(in,&OS,4);
break;
default:
OS = 0;
}
//Print progress info..
printf("\rProcessing [%s]...",efe_name);fflush(stdout);
// Set reading point to start of the data
lseek(in,BLOCK_SIZE, SEEK_SET);
} else {
// EFE from memory (ie. for ex. mkdir)
//====================================
if(media_type == 'f') {
// FILE ACCESS
// Image-file
if((out=open(image_file, O_RDWR | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",image_file));
}
}
// Copy header to Efe (ie. make dir entry)
memcpy(Efe[idx], MemDataHdr, EFE_SIZE);
efe_type = MemDataHdr[1];
if(efe_type == 2) {
// set dir size temporary to 2
efe_blks = 2;
// Root dir has info about parent's index in 'cont'
MemData[16] = 0;
MemData[17] = idx;
} else {
efe_blks = (MemDataHdr[14] << 8) + MemDataHdr[15];
}
}
if(efe_blks > *free_blks) {
EEXIT((stderr,"Not enough free space! %d needed, %d available.\n", efe_blks, *free_blks));
}
first_free_block = 0;
free_start = 0;
free_cnt=0;
// First PASS - Check if enough contiguos blocks
for(i=FAT_START_BLOCK+fat_blks; i<total_blks; i++) {
if(GetFatEntry(media_type,DiskFAT,out,i) == 0) {
//Free block found
if(free_start == 0) {
// Save the num. of the first free block found
if(first_free_block == 0) {
first_free_block = i;
}
free_start = i;
}
free_cnt++;
if(free_cnt == efe_blks) {
// Contiguos blocks found - write whole efe from start_block
if(media_type == 'f') {
// FILE ACCESS
// Copy Blocks
lseek(out, BLOCK_SIZE*free_start , SEEK_SET);
for(j=0; j<efe_blks; j++) {
if(MemData == NULL) {
read(in,Data,BLOCK_SIZE);
} else {
memcpy(Data, MemData, BLOCK_SIZE);
MemData = MemData + BLOCK_SIZE;
}
write(out,Data,BLOCK_SIZE);
}
} else {
// DISK ACCESS
mem_pointer=malloc(BLOCK_SIZE*efe_blks);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
if(MemData == NULL) {
read(in,mem_pointer, BLOCK_SIZE*efe_blks);
} else {
memcpy(mem_pointer, MemData, BLOCK_SIZE*efe_blks);
}
WriteBlocks(media_type,fd,out,free_start,efe_blks,mem_pointer);
free(mem_pointer);
}
// Write FAT
for(j=free_start; j<free_start+efe_blks-1; j++) {
PutFatEntry(media_type,DiskFAT,out, j,j+1);
}
// Mark the end-of-efe
PutFatEntry(media_type,DiskFAT,out, j,1);
efe_start_block = free_start;
first_cont_blks = efe_blks;
break;
}
} else {
free_start = 0;
free_cnt = 0;
}
}
// Second PASS (if needed)
// If there was no enough contiguos blocks, the efe must be
// saved using the space fragments available.. :-(
if(i==total_blks) {
efe_start_block = first_free_block;
prev_block = 0;
free_cnt = 0;
first_cont_blks = 0;
blks=0;
start=0;
// Spilt n' write the efe
for(i=first_free_block; (i<total_blks) || (free_cnt == efe_blks); i++) {
if(free_cnt == efe_blks) break;
// Try to find free space
if(GetFatEntry(media_type,DiskFAT,out,i) == 0) {
if(start==0) start=i;
if(prev_block != 0) {
PutFatEntry(media_type,DiskFAT,out, prev_block,i);
}
prev_block = i;
free_cnt++;
blks++;
} else {
// Calc cont blocks (first entry);
if(first_cont_blks == 0) {
first_cont_blks= i - first_free_block;
}
// process data in chunks (after found free space)
if(blks!= 0) {
// Allocate mem
mem_pointer=malloc(BLOCK_SIZE*blks);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
// Read data
if(MemData == NULL) {
read(in,mem_pointer,BLOCK_SIZE*blks);
} else {
memcpy(mem_pointer, MemData, BLOCK_SIZE*blks);
MemData = MemData + BLOCK_SIZE*blks;
}
// Write data
WriteBlocks(media_type, fd, out, start, blks, mem_pointer);
free(mem_pointer);
start=0;
blks=0;
}
}
}
// Allocate mem
mem_pointer=malloc(BLOCK_SIZE*blks);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
// Read data
if(MemData == NULL) {
read(in,mem_pointer,BLOCK_SIZE*blks);
} else {
memcpy(mem_pointer, MemData, BLOCK_SIZE*blks);
MemData = MemData + BLOCK_SIZE*blks;
}
// Write data
WriteBlocks(media_type, fd, out, start, blks, mem_pointer);
free(mem_pointer);
if(i==total_blks) {
EEXIT((stderr,"ERROR: Image/Disk has a corrupted fat!!\n"));
}
// Mark the end-of-efe
PutFatEntry(media_type,DiskFAT,out, i-1,1);
}
// Update disk-free field
*free_blks = (*free_blks) - efe_blks;
buffer[0] = ((*free_blks) >> 24) & 0x000000ff; // MSB
buffer[1] = ((*free_blks) >> 16) & 0x000000ff;
buffer[2] = ((*free_blks) >> 8) & 0x000000ff;
buffer[3] = (*free_blks) & 0x000000ff; // LSB
if(media_type=='f') {
// FILE ACCESS
lseek(out, OS_BLOCK*BLOCK_SIZE, SEEK_SET);
write(out,buffer,4);
// If OS, update OS-version
if(OS != 0) {
write(out,&OS,4);
}
} else {
// DISK ACCESS
memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE,buffer,4);
// If OS, update OS-version
if(OS != 0) {
memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE+4,&OS,4);
}
}
// Complete DirEntry
// size in blocks
if(efe_type == 2) {
// dir's size = num of files ( = 0 when created)
Efe[idx][14] = 0;
Efe[idx][15] = 0;
} else {
Efe[idx][14] = (unsigned char) (efe_blks >> 8) & 0xFF;
Efe[idx][15] = (unsigned char) (efe_blks & 0xFF);
}
// contiguos blocks
Efe[idx][16] = (unsigned char) (first_cont_blks >> 8);
Efe[idx][17] = (unsigned char) first_cont_blks & 0x00FF;
// start block
Efe[idx][18] = efe_start_block >> 24;
Efe[idx][19] = efe_start_block >> 16;
Efe[idx][20] = efe_start_block >> 8;
Efe[idx][21] = efe_start_block & 0x000000FF;
// Go to Dir entry
// Write System Blocks
if(media_type=='f') {
// FILE ACCESS
lseek(out, dir_start*BLOCK_SIZE + EFE_SIZE*idx , SEEK_SET);
write(out,Efe[idx],EFE_SIZE);
} else {
// DISK ACCESS
// !!!!!
if(dir_start == DIR_START_BLOCK) {
memcpy(DiskHdr+dir_start*BLOCK_SIZE + EFE_SIZE*idx,Efe[idx],EFE_SIZE);
}
//WriteBlocks(media_type,fd,NULL,0,5+fat_blks,DiskHdr);
}
// If Not in Main Dir, update Dir Entries & num. of files in dir
if(dir_start != DIR_START_BLOCK) {
unsigned char ParentEfe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE];
unsigned int parent_dir_idx, parent_dir_files;
// Save changes in curent dir
SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,Efe);
// Get info about parent dir
parent_dir_idx = (unsigned int) ((Efe[0][16] << 8) + Efe[0][17]);
dir_start = (unsigned long) ((Efe[0][18] << 24) + (Efe[0][19] << 16)
+(Efe[0][20] << 8 ) + Efe[0][21]);
// Don't know how many cont blocks so suppose worst case
dir_cont = 1;
// Load parent dir
LoadDirBlocks(media_type,fd,DiskFAT,out,dir_start,dir_cont,ParentEfe);
// Update parent dir 'num. of files'
parent_dir_files =(unsigned int) ((ParentEfe[parent_dir_idx][14] << 8) +
ParentEfe[parent_dir_idx][15]);
parent_dir_files++;
ParentEfe[parent_dir_idx][14] = (unsigned char) (parent_dir_files >> 8) & 0xFF;
ParentEfe[parent_dir_idx][15] = (unsigned char) (parent_dir_files & 0xFF);
// Save changes in parent dir
SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,ParentEfe);
}
optind++;
// KLUDGE!!!
if(MemData != NULL) break;
} // while(efe_files...)
// Free memory used for DiskFat etc. cache
if(media_type != 'f') {
// Write SystemBlocks to disk and free mem
WriteBlocks(media_type,fd,out,0,5+fat_blks,DiskHdr);
free(DiskHdr);
} else {
// Convert to back to orginal format if not raw-image
if((image_type != EPS_TYPE) && (image_type != ASR_TYPE) && (image_type != OTHER_TYPE)) {
if(MemData != NULL) {
close(in);
}
close(out);
ConvertFromImage (image_file, orig_image_name, image_type);
}
}
printf("\r \r");fflush(stdout);
}
/////////////////////////////
// EraseEFEs
int EraseEFEs(char media_type, char image_type, FD_HANDLE fd,
unsigned char *DiskFAT, unsigned char *DiskHdr,
char *in_file, char *orig_image_name,
unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE], char *process_efe,
unsigned int fat_blks, unsigned int *free_blks,
unsigned int dir_start, unsigned int dir_cont)
{
int out;
unsigned int size,cont,start,type,i,j,counter;
unsigned int OS = 1;
unsigned char buffer[4];
counter = 0;
// FILE ACCESS
if(media_type=='f') {
// Image-file
if((out=open(in_file, O_RDWR | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
}
}
// Process Efe's list
for(j=0;j<MAX_NUM_OF_DIR_ENTRIES;j++) {
// Check if current efe has to be processed
if(process_efe[j] == 0) continue;
// Get info
type=Efe[j][1];
switch (type)
{
case 0: // Empty
continue;
case 2: // Sub dir
if(Efe[j][15] > 0) {
fprintf(stderr, "\nIDX %-2d: Can't erase directory! Directory not empty.\n\n",j);
continue;
}
size = 2;
break;
case 8: // Pointer to 'root'
fprintf(stderr, "\nIDX %-2d: Can't erase link to parent dir!\n\n",j);
continue;
// If erasing os, clear version field
case 1:
case 27:
case 32:
OS = 0;
default:
size =(unsigned int) ((Efe[j][14] << 8) + Efe[j][15]);
}
cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
start=(unsigned long) ((Efe[j][18] << 24) + (Efe[j][19] << 16)
+(Efe[j][20] <<8 ) + Efe[j][21]);
// Calculate 'disk-free'
*free_blks = (*free_blks) + size;
// Clear FAT entries
while((i=GetFatEntry(media_type,DiskFAT,out,start)) != 1) {
PutFatEntry(media_type,DiskFAT,out,start,0);
start=i;
}
// .. and last entry (ie. stopmark '1')
PutFatEntry(media_type,DiskFAT,out,start,0);
// Clear Dir entry
for(i=0;i<26;i++) {
Efe[j][i] = 0;
}
// Count erased files for 'num of files' in parent dir
counter++;
} // For 'process_efes'
// Update disk-free field
buffer[0] = ((*free_blks) >> 24) & 0x000000ff; // MSB
buffer[1] = ((*free_blks) >> 16) & 0x000000ff;
buffer[2] = ((*free_blks) >> 8) & 0x000000ff;
buffer[3] = (*free_blks) & 0x000000ff; // LSB
if(media_type=='f') {
// FILE ACCESS
lseek(out, OS_BLOCK*BLOCK_SIZE, SEEK_SET);
write(out,buffer,4);
// If erasing OS, clear OS-field
if(!OS) {
write(out,&OS,4);
}
} else {
// DISK ACCESS
memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE,buffer,4);
// If erasing OS, clear OS-field
if(!OS) {
memcpy(DiskHdr+OS_BLOCK*BLOCK_SIZE+4,&OS,4);
}
}
// Write System Blocks
if(media_type != 'f') {
// DISK ACCESS
WriteBlocks(media_type,fd,out,0,5+fat_blks,DiskHdr);
}
// Update Dir Entries
SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,Efe);
// If Not in Main Dir, update Dir Entries & num. of files in dir
if(dir_start != DIR_START_BLOCK) {
unsigned char ParentEfe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE];
unsigned int parent_dir_idx, parent_dir_files;
// Get info about parent dir
parent_dir_idx = (unsigned int) ((Efe[0][16] << 8) + Efe[0][17]);
dir_start = (unsigned long) ((Efe[0][18] << 24) + (Efe[0][19] << 16)
+(Efe[0][20] << 8 ) + Efe[0][21]);
// Don't know how many cont blocks so suppose worst case
dir_cont = 1;
// Load parent dir
LoadDirBlocks(media_type,fd,DiskFAT,out,dir_start,dir_cont,ParentEfe);
// Update parent dir 'num of files'
parent_dir_files =(unsigned int) ((ParentEfe[parent_dir_idx][14] << 8) +
ParentEfe[parent_dir_idx][15]);
// Decrement 'num. of files' in parent dir
parent_dir_files = parent_dir_files - counter;
// if everything is OK, this _should_ NOT happen...
if(parent_dir_files < 0) parent_dir_files = 0;
ParentEfe[parent_dir_idx][14] = (unsigned char) (parent_dir_files >> 8) & 0xFF;
ParentEfe[parent_dir_idx][15] = (unsigned char) (parent_dir_files & 0xFF);
// Save changes in parent dir
SaveDirBlocks(media_type, fd, DiskFAT, out, dir_start, dir_cont,ParentEfe);
}
// Free memory used for DiskFat etc. cache
if(media_type != 'f') {
free(DiskHdr);
} else {
// Convert to back to orginal format if not raw-image
if((image_type != EPS_TYPE) && (image_type != ASR_TYPE) && (image_type != OTHER_TYPE)) {
close(out);
ConvertFromImage (in_file, orig_image_name, image_type);
}
}
return(OK);
}
//////////////////
// MkDir
int MkDir(
char *process_efe,
unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
char media_type,
char image_type,
char *image_file,
char *orig_image_name,
unsigned int dir_start,
unsigned int dir_cont,
char *dir_name,
unsigned int total_blks,
unsigned int *free_blks,
unsigned int fat_blks,
FD_HANDLE fd,
unsigned char *DiskFAT,
unsigned char *DiskHdr,
char DirName[12]
)
{
unsigned char MemDataHdr[EFE_SIZE], *MemData;
int i;
for(i=0; i < EFE_SIZE; i++) {
MemDataHdr[i] = 0;
}
// Convert name
for(i=0; i < 12; i++) {
DirName[i] = (unsigned char) toupper(DirName[i]);
}
// Make header
// Type (2)
MemDataHdr[1] = 2;
// Name
for(i=0; i<12; i++) {
if(DirName[i] == 0) {
MemDataHdr[2+i] = 0x20;
} else {
MemDataHdr[2+i] = DirName[i];
}
}
// Size (2)
MemDataHdr[15] = 2;
// Make data
// 2 x Blocks
MemData=calloc(2*BLOCK_SIZE,sizeof(unsigned char));
if(MemData == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
// First entry is root-dir
// Type (8)
MemData[1] = 8;
// Name of parent dir
strncpy(MemData+2, dir_name, 12);
// Cont ( < 255!!)
MemData[17] = (unsigned char) dir_cont;
// Root Dir start block
MemData[18] = (dir_start >> 24) & 0x000000FF;
MemData[19] = (dir_start >> 16) & 0x000000FF;
MemData[20] = (dir_start >> 8) & 0x000000FF;
MemData[21] = dir_start & 0x000000FF;
// 'DR'
MemData[2*BLOCK_SIZE-2] = 0x44; MemData[2*BLOCK_SIZE-1] = 0x52;
// Write dir
PutEFE(process_efe, 1, Efe, media_type, image_type,
image_file, NULL, 0, orig_image_name,
dir_start, dir_cont, total_blks, free_blks, fat_blks,
fd, DiskFAT, DiskHdr, MemDataHdr, MemData);
return(OK);
}
/////////////////////////////
// SplitEfe
void SplitEfe(char *in_file, char *slice_type, int argc)
{
int in, out;
struct stat stat_buf;
unsigned int i,slice_size, slice_count, data_len;
unsigned char Data[BLOCK_SIZE];
unsigned char Hdr[BLOCK_SIZE];
char out_file[FILENAME_MAX],out_file_head[12], out_file_tail[FILENAME_MAX];
// Check arguments
if((argc != 4) || ((strcasecmp(slice_type,"eps") != 0) && (strcasecmp(slice_type,"asr") != 0))) {
fprintf(stderr,"ERROR: Invalid or wrong number of arguments\n");
ShowUsage();
exit(ERR);
}
if(strcasecmp(slice_type,"eps") == 0) {
slice_size = 1585 * BLOCK_SIZE;
} else {
slice_size = 3176 * BLOCK_SIZE;
}
// Open input Efe file
if((in=open(in_file, O_RDONLY | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
}
// Get filesize
if(stat(in_file,&stat_buf) != 0) {
EEXIT((stderr,"\n(line: %d) ERROR: Can't get the filesize!!\n", __LINE__));
}
data_len = stat_buf.st_size - BLOCK_SIZE;
// Check the validity of the given filesize ie. that is multiple of block size
if((data_len % BLOCK_SIZE) != 0) {
EEXIT((stderr,"Image size have to be multiple of %d!\n",BLOCK_SIZE));
}
// Check if split is needed..
if(data_len <= slice_size) {
printf("No split needed. EFE will fit in one disk!\n");
exit(OK);
}
// ASR max mem 16M!
if(data_len > 16777216 ) {
EEXIT((stderr,"EFE is too big! Maybe corrupted !?\n"));
}
// Read Efe Header
//fseek(in, 512,0);
read(in,&Hdr, BLOCK_SIZE);
// Check Efe type
if(Hdr[0x32] != 3) {
EEXIT((stderr,"ERROR: File '%s' is not an INSTRUMENT type.\n",in_file));
}
// Check filesize and Efe header blocksize match..
if(((data_len / BLOCK_SIZE) != ( ((Hdr[0x34] << 8) + Hdr[0x35])))) {
EEXIT((stderr,"ERROR: File size and block size in Efe header doesn't match!\n"));
}
// If Efe is named using EpsLin "format"
if(strncmp("[Instr ]",in_file+4,9) == 0) {
in_file[10]='\0';
strcpy(out_file_head,in_file);
strcpy(out_file_tail,in_file+12);
} else {
strcpy(out_file_head ,"Part_");
sprintf(out_file_tail,"_%s", in_file);
}
slice_count=0;
printf("\nSplitting in progress:\n");
// Split
while(data_len > 0) {
// Seek imputfile
lseek(in, BLOCK_SIZE + slice_count*slice_size,0);
// Construct output filename
slice_count++;
sprintf(out_file,"%s%02d%s",out_file_head, slice_count, out_file_tail);
if((out=open(out_file, O_RDWR | O_CREAT | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",out_file));
}
printf("\rWriting MultiFile EFE #%d",slice_count);
// If last slice...
if(data_len < slice_size) slice_size=data_len;
// Generate EFE header
Hdr[0x34] = ((slice_size/BLOCK_SIZE) & 0xFF00) >> 8; // Blocks
Hdr[0x35] = ((slice_size/BLOCK_SIZE) & 0x00FF);
Hdr[0x3a] = slice_count; // Multifile
// Write header
write(out,Hdr,BLOCK_SIZE);
// Copy data
for(i=0;i<slice_size;i=i+BLOCK_SIZE) {
read(in,Data,BLOCK_SIZE);
write(out,Data,BLOCK_SIZE);
}
data_len=data_len - slice_size;
} // while
printf("\rEFE slpitting OK! \n");
close(in);close(out);
}
/////////////////////////////
// JoinEfe
void JoinEfes (int argc, char **argv) {
int in, out;
unsigned char Data[BLOCK_SIZE];
unsigned char Hdr[BLOCK_SIZE];
char out_file[FILENAME_MAX];
char in_file[FILENAME_MAX];
struct stat stat_buf;
unsigned int i, slice_idx, data_len, data_total;
// Check arguments
if( argc < 5 ) {
fprintf(stderr,"ERROR: Invalid or wrong number of arguments\n");
ShowUsage();
exit(ERR);
}
sprintf(out_file,argv[2]);
// Open Output file
if((out=open(out_file, O_RDWR | O_CREAT | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",out_file));
}
slice_idx=0;
data_total=0;
while(slice_idx < (argc-3)) {
strcpy(in_file,argv[slice_idx+3]);
printf("Processin Efe part #%d: %s\n",slice_idx+1,in_file);
// Open input Efe file
if((in=open(in_file, O_RDONLY | O_BINARY)) < 0) {
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
}
// Get filesize
if(stat(in_file,&stat_buf) != 0) {
EEXIT((stderr,"\n(line: %d) ERROR: Can't get the filesize!!\n", __LINE__));
}
data_len = stat_buf.st_size - BLOCK_SIZE;
// Check the validity of the given filesize ie. that is multiple of block size
if((data_len % BLOCK_SIZE) != 0) {
EEXIT((stderr,"Image size have to be multiple of %d!\n",BLOCK_SIZE));
}
// Read Efe Header
read(in,&Hdr, BLOCK_SIZE);
// Check Efe type
if(Hdr[0x32] != 3) {
EEXIT((stderr,"ERROR: File '%s' is not an INSTRUMENT type.\n",in_file));
}
// Check filesize and Efe header blocksize match..
if(((data_len / BLOCK_SIZE) != ( ((Hdr[0x34] << 8) + Hdr[0x35])))) {
EEXIT((stderr,"ERROR: File size and block size in Efe header doesn't match!\n"));
}
// Copy header before first slice..
if(slice_idx==0) {
write(out,Hdr,BLOCK_SIZE);
}
// Copy data
for(i=0;i<data_len;i=i+BLOCK_SIZE) {
read(in,Data,BLOCK_SIZE);
write(out,Data,BLOCK_SIZE);
}
data_total=data_total+data_len;
slice_idx++;
}// while
//Fix the final header of the output file
// Generate EFE header
Hdr[0x34] = ((data_total/BLOCK_SIZE) & 0xFF00) >> 8; // Blocks
Hdr[0x35] = ((data_total/BLOCK_SIZE) & 0x00FF);
Hdr[0x3a] = 0; // Singlefile
// Overwrite header
lseek(out, 0L, SEEK_SET);
write(out,Hdr,BLOCK_SIZE);
printf("Join operation OK! Total size of the joined EFE is %d blocks.\n\n",data_total/BLOCK_SIZE);
close(in);close(out);
}
/////////////////////////////
// DoConversion
void DoConversion(char in_file[FILENAME_MAX], char out_file[FILENAME_MAX], int argc)
{
struct stat stat_buf;
char image_type;
if(argc != 4) {
fprintf(stderr,"ERROR: Wrong number of arguments\n");
ShowUsage();
exit(ERR);
}
if(ConvertToImage(in_file,out_file) == OK) {
printf("CONVERSION DONE!!!\n");
exit(OK);
}
// No conversion - suppose img-file
// Check if ASR or EPS image
if(stat(in_file,&stat_buf) != 0) {
EEXIT((stderr,"ERROR: Can't get the filesize!!\n"));
}
if(stat_buf.st_size == EPS_IMAGE_SIZE) {
image_type = EDE_TYPE;
} else if(stat_buf.st_size == ASR_IMAGE_SIZE) {
image_type = EDA_TYPE;
} else {
EEXIT((stderr,"ERROR: Unsupported image type!\n\n"));
}
ConvertFromImage (in_file,out_file, image_type);
printf("Conversion succesfully!\n");
}
/////////////////////////////////////////
// GetMedia
// ------------
// - Determines if disk or image is used,
// and does nessecery opening and conversions
void GetMedia(char *arg, int argc, char *media_type, char *image_type,
unsigned int *nsect, unsigned int *trk_size, FD_HANDLE *fd,
char *in_file, int *in)
{
unsigned int tmp;
// Determines is DISK or FILE access
// TODO: THIS IS EXPERIMENTAL
if((arg == NULL) || ((IsEFE(arg) == OK) && (argc >= 3))) {
// DISK ACCESS
if(FD_GetDiskType(media_type,nsect,trk_size) == ERR) {
EEXIT((stderr,"ERROR: NOT an Ensoniq Disk.\n Please format the disk (-fe or -fa) and try again!!\n\n"));
}
//Open FD
*fd=OpenFloppy(0);
} else {
// FILE ACCESS
*media_type='f';
// Get the image filename
strcpy(in_file,arg);
GetImageType(in_file, image_type);
// Check if conversion is needed!
if((*image_type != EPS_TYPE) && (*image_type != ASR_TYPE) && (*image_type != OTHER_TYPE)) {
// Generate tmp-file and bind the clean-up for it
//tmpnam(tmp_file);
mkstemp(tmp_file);
atexit(CleanTmpFile);
if(ConvertToImage(in_file,tmp_file) == OK) {
//repalace in_file to converted image
strcpy(in_file,tmp_file);
}
}
if((*in =open(in_file, O_RDONLY | O_BINARY)) < 0) {
perror("open:");
EEXIT((stderr,"ERROR: Couldn't open file '%s'.\n",in_file));
}
if(IsEFE(in_file) != OK) {
// Check that EPS/ASR image is valid! (ie. do the 'ID-check')
lseek(*in, (long) 0x224, SEEK_SET);
read(*in,&tmp,4);
if((tmp & 0xffff0000) != 0x44490000) {
EEXIT((stderr,"ERROR: Not a valid image file!\n"));
}
}
}
}
////////////////////////////////////////////////////
// GetInfo
// -------
// -Get info about used media and loads the selected
// directory structure.
//
void GetInfo(char *media_type, FD_HANDLE fd, unsigned char **DiskFAT, unsigned char **DiskHdr,
int in,
unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE],
unsigned int *fat_blks, unsigned int *free_blks, unsigned int *total_blks,
unsigned int *dir_start, unsigned int *dir_cont,
char *parent_dir_name, int subdir_cnt,
unsigned int *DirPath, char *DiskLabel)
{
unsigned char *mem_pointer;
unsigned int tmp,i,j;
if(*media_type=='f') {
// FILE ACCESS
mem_pointer=malloc(5*BLOCK_SIZE);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
ReadBlocks(*media_type,fd,in,0,5,mem_pointer);
} else {
// DISK ACCESS
if(*media_type=='e') *fat_blks=10; else *fat_blks=19;
mem_pointer=malloc((5+(*fat_blks))*BLOCK_SIZE);
if(mem_pointer == NULL) EEXIT((stderr,"ERROR: Couldn't allocate memory !!!!\n"));
ReadBlocks(*media_type,fd,in,0,5+(*fat_blks),mem_pointer);
*DiskHdr=mem_pointer;
*DiskFAT=mem_pointer+FAT_START_BLOCK*BLOCK_SIZE;
}
// Get 'TotalBlocks' and 'DiskLabel' from ID_BLOCK
tmp=ID_BLOCK*BLOCK_SIZE;
*total_blks = (unsigned int) ((mem_pointer[tmp+14] << 24) +
(mem_pointer[tmp+15] << 16) +
(mem_pointer[tmp+16] << 8 ) +
(mem_pointer[tmp+17] & 0x000000ff));
strncpy(DiskLabel, mem_pointer+tmp+31,7);
DiskLabel[7]='\0';
if(strlen(DiskLabel) == 0) strcpy(DiskLabel,"<NONE>");
*fat_blks = (*total_blks /170) + 1;
// Get 'FreeBlocks' from OS_BLOCK
tmp=OS_BLOCK*BLOCK_SIZE;
*free_blks = (unsigned int) ((mem_pointer[tmp] << 24) +
(mem_pointer[tmp+1] << 16) +
(mem_pointer[tmp+2] << 8 ) +
(mem_pointer[tmp+3] & 0x000000ff));
// Load main directory
*dir_start=DIR_START_BLOCK;
*dir_cont = 2;
// Scan Main Directory
for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
for(j=0; j < EFE_SIZE ; j++) {
Efe[i][j]=mem_pointer[DIR_START_BLOCK*BLOCK_SIZE + i * EFE_SIZE + j];
}
}
//LoadDirBlocks(media_type,fd,DiskFAT,in,dir_start,dir_cont,Efe);
// SUB-DIRS - Use the 'path' to 'change dir'...
if(subdir_cnt >0) {
for(i=0; i < subdir_cnt; i++) {
j=DirPath[i];
if (Efe[j][1] != 2) {
EEXIT((stderr,"ERROR: Index '%d' is not a directory!\n\n",j));
}
strncpy(parent_dir_name, Efe[j]+2, 12);
*dir_cont =(unsigned int) ((Efe[j][16] << 8) + Efe[j][17]);
*dir_start =(unsigned long) ((Efe[j][18] << 24) + (Efe[j][19] << 16)
+(Efe[j][20] << 8 ) + Efe[j][21]);
LoadDirBlocks(*media_type,fd,*DiskFAT,in,*dir_start,*dir_cont,Efe);
}
} else {
// if parent is root dir, set parent_name to 'ROOT'
strncpy(parent_dir_name,"ROOT ", 12);
}
}
////////////////////////////////////////////////////
// CheckMedia
// ----------
// -Get info about used media and check the filesystem
// structure
void CheckMedia(char media_type, FD_HANDLE fd, int file, int check_level)
{
unsigned long i,j,count,used_blks;
unsigned char buffer[BLOCK_SIZE],*root_dir;
unsigned long total_blks,free_blks;
unsigned long file_size;
//Get File/Device info
if(media_type=='f') {
// FILE ACCESS
if((file_size=lseek(file,0,SEEK_END)) == -1) {
perror("lseek");
exit(ERR);
}
} else {
// DISK ACCESS
if((file_size=lseek(fd,0,SEEK_END)) == -1) {
perror("lseek");
exit(ERR);
}
}
printf("\nFile/Device size: %ld bytes (%ld blocks)\n\n",file_size,file_size/BLOCK_SIZE);
//ID-Block
ReadBlocks(media_type,fd,file,ID_BLOCK,1,buffer);
printf("\nID-BLOCK\n");
printf("========\n\n");
printf("Device type : %d(%x)\n" ,buffer[0],buffer[0]);
printf("Rem. Media Device type : %d(%x)\n" ,buffer[1],buffer[1]);
printf("Std.Version# : %d(%x)\n" ,buffer[2],buffer[2]);
printf("SCSI (?) : %d(%x)\n" ,buffer[3],buffer[3]);
printf("Number of Sectors : %d(%x%x)\n",(buffer[4]*256+buffer[5]),buffer[4],buffer[5]);
printf("Number of Heads : %d(%x%x)\n",(buffer[6]*256+buffer[7]),buffer[6],buffer[7]);
printf("Number of Tracks : %d(%x%x)\n",(buffer[8]*256+buffer[9]),buffer[8],buffer[9]);
printf("Bytes per Block (512) : %d(%x%x)\n",(buffer[12]*256+buffer[13]),buffer[12],buffer[13]);
total_blks = ((buffer[14] << 24) +
(buffer[15] << 16) +
(buffer[16] << 8 ) +
(buffer[17] & 0x000000ff));
printf("Total Blocks : %ld(%x%x%x%x) (%ld Bytes = %ld KBytes = %ld MBytes)\n",
total_blks,
buffer[14],buffer[15],buffer[16],buffer[17],
total_blks*512,total_blks*512/1024,total_blks*512/1024/1024);
printf("SCSI Medium type : %d(%x)\n" ,buffer[18],buffer[18]);
printf("SCSI Density Code : %d(%x)\n" ,buffer[19],buffer[19]);
printf("DISK LABEL : \"%c%c%c%c%c%c%c\" \n",buffer[31],buffer[32],buffer[33],
buffer[34],buffer[35],buffer[36],buffer[37]);
printf("End of ID-Block(\"ID\") : \"%c%c\"\n",buffer[38],buffer[39]);
//OS-Block
ReadBlocks(media_type,fd,file,OS_BLOCK,1,buffer);
printf("\nOS-BLOCK\n");
printf("========\n\n");
free_blks = ((buffer[0] << 24) +
(buffer[1] << 16) +
(buffer[2] << 8 ) +
(buffer[3] & 0x000000ff));
printf("Free Blocks : %ld(%x%x%x%x)\n",free_blks,
buffer[0],buffer[1],buffer[2],buffer[3]);
printf("Disk OS Version : %d.%d(%x.%x)\n" ,buffer[4],buffer[5],buffer[4],buffer[5]);
printf("ROM OS Version : %d.%d(%x.%x)\n" ,buffer[6],buffer[7],buffer[6],buffer[7]);
printf("End of OS-Block(\"OS\") : \"%c%c\"\n",buffer[28],buffer[29]);
printf("\nOther Blocks\n");
printf("============\n\n");
count=0;
used_blks=0;
ReadBlocks(media_type,fd,file,DIR_END_BLOCK,1,buffer);
printf("Root DirBlocks : ");
if(buffer[510]=='D' && buffer[511]=='R')
printf("OK\n");
else
printf("NOT OK - DISK/FILE is corrupted!\n");
for(i=FAT_START_BLOCK;;i++) {
ReadBlocks(media_type,fd,file,i,1,buffer);
//Check if valid FAT BLOCK
if(buffer[510]!='F' || buffer[511]!='B')
break;
//Count used blocks
for(j=2;j<510;j=j+3) {
if( !((buffer[j] == 0) && (buffer[j-1] ==0) && (buffer[j-2]==0)))
used_blks++;
}
count++;
}
printf("Num. of FatBlocks : %ld\n",count);
printf("FAT entries : %ld => ",170*count);
if((170*count) >= total_blks)
printf("OK\n");
else
printf("FAT corrupted!! Not enough FAT tables!\n");
printf("Used Blocks in FAT: %ld => ",used_blks);
if( (total_blks - (used_blks+free_blks)) == 0)
printf("OK\n");
else
printf("FAT corrupted!! Used blocks should be %ld\n",total_blks - free_blks);
printf("\n");
// If higher check_level, display also root dir structure
if(check_level > 0) {
// Directory structure info
printf("\nROOT DIR:\n");
printf("=========\n");
root_dir=(unsigned char *) malloc(BLOCK_SIZE*2);
ReadBlocks(media_type,fd,file,DIR_START_BLOCK,2,root_dir);
// Scan Directory
for(i=0;i<MAX_NUM_OF_DIR_ENTRIES;i++) {
char name[13];
printf("%3ld:",i);
for(j=0; j < EFE_SIZE ; j++) {
printf("%02x ",root_dir[i * EFE_SIZE+j]);
}
printf("\n");
strncpy(name, &root_dir[i * EFE_SIZE+2],12);
name[12]='\0';
printf(" Type:%2d, Name:%12s, Size:%ld, Cont:%ld, Start:%ld \n\n",
root_dir[i * EFE_SIZE+1],
name,
(long) root_dir[i * EFE_SIZE+14]*256+root_dir[i * EFE_SIZE+15],
(long) root_dir[i * EFE_SIZE+16]*256+root_dir[i * EFE_SIZE+17],
(long) root_dir[i * EFE_SIZE+18]*256*256*256+root_dir[i * EFE_SIZE+19]*256*256 +
root_dir[i * EFE_SIZE+20]*256+root_dir[i * EFE_SIZE+21]
);
}
free(root_dir);
}
}
////////////////////////////////////////////////////
// Confirm
// -------
// -Asks if user wants to proceed
void Confirm()
{
}
///////////////////////
// ImageCopy
// ----------
// -Copy image file to another one. Use to copy
// for ex. CD-ROM to HD etc.
int ImageCopy(char *source_file_name, char *target_file_name)
{
//FILE *source, *target;
unsigned int i=0;
unsigned long source_file_size, target_file_size;
unsigned char buffer[IMAGE_COPY_BUFFER_BLOCKS*BLOCK_SIZE];
int source,target;
unsigned int read_bytes,write_bytes;
printf("\n");
// Open source file and get file size
if( (source=open(source_file_name,O_RDONLY | O_BINARY)) < 0) {
perror("open:");
EEXIT((stderr,"ERROR: Couldn't open source file '%s'.\n",source_file_name));
}
source_file_size=lseek(source, 0, SEEK_END);
// Check validity of source file
if(source_file_size == 0)
EEXIT((stderr,"ERROR: Source file '%s' is empty.\n",source_file_name));
if((source_file_size % BLOCK_SIZE) != 0) {
EEXIT((stderr,"Source size have to be multiple of block size %d!\n",BLOCK_SIZE));
exit(ERR);
}
if((target=open(target_file_name,O_RDWR | O_BINARY)) < 0) {
if((target=open(target_file_name,O_RDWR | O_CREAT | O_BINARY ,S_IRWXU)) < 0) {
perror("open:");
EEXIT((stderr,"ERROR: Couldn't open target file '%s'.\n",target_file_name));
}
printf("Creating new file '%s'\n", target_file_name);
}
target_file_size=lseek(target,0,SEEK_END);
if(target_file_size == 0) {
printf("Creating target file %s\n",target_file_name);
} else {
if(source_file_size > target_file_size) {
EEXIT((stderr,"ERROR: Couldn't fit!\nSource '%s' is BIGGER that target '%s'.\n\nSource size: %ld Bytes, target size %ld Bytes\n\n",
source_file_name, target_file_name,source_file_size,target_file_size));
}
}
printf("s:%ld,t:%ld\n",source_file_size,target_file_size);
if(lseek(source,0,SEEK_SET) < 0) {
perror("seek");
return(ERR);
}
if(lseek(target,0,SEEK_SET) < 0) {
perror("seek");
return(ERR);
}
// Do copy in big chunks...
do {
read_bytes=read(source,buffer,IMAGE_COPY_BUFFER_BLOCKS*BLOCK_SIZE);
if(read_bytes < 0) {
perror("read");
return(ERR);
}
// if last read was "full" read, but get all the data left, next read is 0
if(read_bytes == 0) break;
printf("\rCopying image file... %d%% completed",((100*i++) / ((source_file_size / BLOCK_SIZE) / IMAGE_COPY_BUFFER_BLOCKS)) );
write_bytes=write(target,buffer,read_bytes);
if(write_bytes< 0) {
perror("write");
return(ERR);
}
} while (read_bytes == (IMAGE_COPY_BUFFER_BLOCKS*BLOCK_SIZE));
printf("\rImage copy from '%s' to '%s' done! Total %ld Bytes copied. \n",source_file_name,target_file_name,source_file_size);
fflush(stdout);
close(source);close(target);
return(OK);
}
//################################################################
// MAIN PROGRAM ###############################################
//##############################################################
int main(int argc, char **argv)
{
int in;
unsigned char Efe[MAX_NUM_OF_DIR_ENTRIES][EFE_SIZE];
unsigned char *DiskFAT,*DiskHdr, *mem_pointer;
char DiskLabel[DISK_LABEL_SIZE];
unsigned int DirPath[MAX_DIR_DEPTH], subdir_cnt;
unsigned int total_blks, free_blks, fat_blks;
unsigned int dir_start, dir_cont, start_idx;
unsigned long i,j;
char c, media_type, image_type, process_efe[MAX_NUM_OF_DIR_ENTRIES], in_file[FILENAME_MAX];
char mkdir_name[12], parent_dir_name[12];
char format_arg;
FD_HANDLE fd;
int mode, trk_size, nsect,printmode;
int check_level, confirm_operation;
// Initialize variables
mode = NONE; subdir_cnt = 0; j = 0; image_type= -1; printmode = HUMAN_READABLE;
trk_size = 0; media_type = 0; fat_blks = 0; in = 0;
DiskFAT = NULL; mem_pointer=NULL; start_idx = 1;
confirm_operation = 0;
strncpy(DiskLabel,DEFAULT_DISK_LABEL,DISK_LABEL_SIZE);
fd= (FD_HANDLE) NULL;
for(i=0;i < MAX_NUM_OF_DIR_ENTRIES; i++) process_efe[i]=0;
printf("\n");
// Get options and parameters
while (1)
{
c = getopt(argc, argv, "Pj:b:srwf:g:p::e:d:m:itc:C::l:qI");
if (c == -1)
break;
switch (c)
{
case 'b': // ** Bank Info **
PrintBankInfo(optarg,printmode);
printf("%d,%s\n",printmode,optarg);
exit(OK);
break;
case 'P': // ** COPUTER READABLE DIRLIST **
printmode = COMPUTER_READABLE;
break;
case 's': // ** SPLIT EFE **
SplitEfe(argv[2], argv[3], argc);
exit(OK);
break;
case 'j': // ** JOIN EFEs **
JoinEfes(argc,argv);
exit(OK);
break;
case 't': // ** TEST **
//EEXIT((stderr,"ERROR: No test-modes!\n"));
mode = TEST;
break;
case 'C': // ** CHECK MEDIA **
printf("argv[optind=%d]=%s,argc=%d\n",optind,argv[optind],argc);
GetMedia(argv[optind], argc, &media_type, &image_type, &nsect, &trk_size, &fd, in_file, &in);
if(optarg==NULL) check_level=0; else check_level=*optarg-'0';
CheckMedia(media_type, fd, in, check_level);
exit(OK);
break;
case 'c': // ** CONVERT **
DoConversion(argv[2], argv[3], argc);
exit(OK);
break;
case 'i': // ** INFO **
if(FD_GetDiskType(&media_type,&nsect,&trk_size) == ERR) {
EEXIT((stderr,"ERROR: NOT an Ensoniq Disk.\n Please format the disk (-fe or -fa) and try again!!\n\n"));
}
exit(OK);
break;
case 'I': // ** IMAGE COPY ***
if(confirm_operation ==0) Confirm();
printf("source=%s,target=%s\n",argv[optind],argv[optind+1]);
ImageCopy(argv[optind],argv[optind+1]);
exit(OK);
break;
case 'r': // ** READ DISK to IMAGE **
mode = READ;
confirm_operation++;
break;
case 'w': // ** WRITE DISK from IMAGE **
mode = WRITE;
confirm_operation++;
break;
case 'f': // ** FORMAT DISK/IMAGE **
mode=FORMAT;
confirm_operation++;
format_arg=optarg[0];
break;
case 'l':
strncpy(DiskLabel,optarg,DISK_LABEL_SIZE);
break;
case 'g': // ** Get EFEs **
ParseEntry(optarg,process_efe);
mode=GET;
break;
case 'p': // ** Put EFEs **
if(optarg != NULL) {
start_idx = atoi(optarg);
}
mode=PUT;
break;
case 'e': // ** Erase EFEs **
ParseEntry(optarg,process_efe);
mode=ERASE;
break;
case 'd': // ** Directory **
ParseDir(optarg, DirPath, &subdir_cnt);
printf("DirPath:%s\n",optarg);
break;
case 'm': // ** Make directory **
mode=MKDIR;
strncpy(mkdir_name, optarg,12);
break;
case 'q': // Quiet mode //
confirm_operation--;
break;
case '?':
ShowUsage();
return(ERR);
break;
default:
printf("DEFAULT\n");
printf ("\n");
}
}
if(mode == FORMAT) {
if(confirm_operation) Confirm();
FormatMedia(argv, argc, optind, format_arg, DiskLabel);
}
// If other than disk read/write/format, get info etc..
//if((mode != WRITE) && (mode != READ) && (mode != FORMAT)) {
if((mode != WRITE) && (mode != READ)) {
// Check if DISK or FILE access and get media parameters
#ifdef DEBUG
printf("GETMEDIA\n");fflush(stdout);
#endif
GetMedia(argv[optind], argc, &media_type, &image_type,
&nsect, &trk_size, &fd, in_file, &in);
#ifdef DEBUG
printf("media_type=%c\n",media_type);
#endif
// GET DIR & MISC INFO
#ifdef DEBUG
printf("GETINFO\n");fflush(stdout);
#endif
GetInfo(&media_type, fd, &DiskFAT, &DiskHdr, in, Efe,
&fat_blks, &free_blks, &total_blks, &dir_start, &dir_cont,
parent_dir_name, subdir_cnt, DirPath, DiskLabel);
}
// Select operation mode (if any)
// ==============================
switch (mode)
{
case READ: // Read/Wite DISK
case WRITE:
if(confirm_operation) Confirm();
FD_RW_Disk(argv[optind], mode);
exit(OK);
case GET: // Get EFEs
GetEFEs(media_type, fd, in, Efe, process_efe, DiskFAT);
break;
case PUT: // Put EFEs
#ifdef DEBUG
printf("PUTEFE\n");fflush(stdout);
#endif
PutEFE(process_efe, start_idx, Efe, media_type, image_type,
in_file, argv, optind, argv[optind],
dir_start, dir_cont, total_blks, &free_blks, fat_blks,
fd, DiskFAT, DiskHdr, NULL, NULL);
break;
case ERASE: // Erase EFEs
EraseEFEs(media_type, image_type, fd, DiskFAT, DiskHdr, in_file, argv[optind],
Efe, process_efe,
fat_blks, &free_blks, dir_start, dir_cont);
break;
case MKDIR: // Make Dir
MkDir(process_efe, Efe, media_type, image_type,
in_file, argv[optind],
dir_start, dir_cont, parent_dir_name, total_blks,
&free_blks, fat_blks,
fd, DiskFAT, DiskHdr, mkdir_name);
break;
case TEST:
printf("\nFAT:\n");
for(i=0 ; i<total_blks; i++) {
switch(GetFatEntry(media_type,DiskFAT,in,i)) {
case 0:
printf(".");
break;
case 1:
printf("E");
break;
default:
printf("#");
}
}
printf("\n");
exit(0);
}
// Close file-pointers if needed
if(in != 0) close(in);
if(fd != (FD_HANDLE) NULL) {
CloseFloppy(fd);
}
#ifdef DEBUG
printf("PRINTDIR\n");fflush(stdout);
#endif
// Print the DirectoryList - Uses 'original' filename (not tmp :-)
PrintDir(Efe, mode, process_efe, argv[optind], media_type, DiskLabel,
free_blks, (total_blks - free_blks - fat_blks - 5),printmode);
exit(OK);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment