mirror of
https://github.com/jfdelnero/HxCFloppyEmulator.git
synced 2026-07-27 19:56:23 +00:00
2616 lines
68 KiB
C
2616 lines
68 KiB
C
/*
|
|
//
|
|
// Copyright (C) 2006-2025 Jean-François DEL NERO
|
|
//
|
|
// This file is part of the HxCFloppyEmulator library
|
|
//
|
|
// HxCFloppyEmulator may be used and distributed without restriction provided
|
|
// that this copyright statement is not removed from the file and that any
|
|
// derivative work contains the original copyright notice and the associated
|
|
// disclaimer.
|
|
//
|
|
// HxCFloppyEmulator 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.
|
|
//
|
|
// HxCFloppyEmulator 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 HxCFloppyEmulator; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
//
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//-------------------------------------------------------------------------------//
|
|
//-------------------------------------------------------------------------------//
|
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
|
//-------------------------------------------------------------------------------//
|
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// File : floppy_loader.c
|
|
// Contains: Library interface functions
|
|
//
|
|
// Written by: Jean-François DEL NERO
|
|
//
|
|
// Change History (most recent first):
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "types.h"
|
|
|
|
#include "internal_libhxcfe.h"
|
|
#include "tracks/track_generator.h"
|
|
#include "floppy_builder.h"
|
|
#include "libhxcfe.h"
|
|
#include "floppy_loader.h"
|
|
#include "floppy_utils.h"
|
|
|
|
#include "loaders_list.h"
|
|
|
|
#include "tracks/std_crc32.h"
|
|
|
|
#include "version.h"
|
|
#include "licensetxt.h"
|
|
|
|
#include "plugins_id.h"
|
|
|
|
#include "libhxcadaptor.h"
|
|
|
|
#include "misc/env.h"
|
|
#include "misc/script_exec.h"
|
|
|
|
#include "init_script.h"
|
|
|
|
#include "xml_disk/packer/pack.h"
|
|
|
|
#include "tracks/track_types_defs.h"
|
|
|
|
|
|
int dummy_output(int MSGTYPE,const char * chaine, ...)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int dummy_trackpos(unsigned int current,unsigned int total)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int dummy_progress(unsigned int current,unsigned int total, void * user)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
HXCFE* hxcfe_init(void)
|
|
{
|
|
HXCFE* hxcfe;
|
|
HXCFE_IMGLDR *imgldr_ctx;
|
|
image_plugin* plugin_ptr;
|
|
char * savefilepath;
|
|
int nb_loader;
|
|
int nb_xml_loader;
|
|
int i,j;
|
|
int ret;
|
|
unsigned char * init_script_buf;
|
|
|
|
init_script_buf = NULL;
|
|
|
|
hxcfe = calloc( 1 ,sizeof(HXCFE) );
|
|
if( hxcfe )
|
|
{
|
|
hxcfe->hxc_printf = &dummy_output;
|
|
hxcfe->hxc_settrackpos = &dummy_trackpos;
|
|
|
|
hxcfe->envvar = initEnv( NULL, NULL );
|
|
hxcfe_setEnvVar(hxcfe, "LIBVERSION", "v"STR_FILE_VERSION2);
|
|
|
|
if ( hxcfe_initScript(hxcfe) != HXCFE_NOERROR )
|
|
goto init_error;
|
|
|
|
hxcfe->hxc_printf(MSG_INFO_0,"Starting HxCFloppyEmulator...");
|
|
|
|
init_script_buf = data_unpack(data_init_script->data,data_init_script->csize,0,data_init_script->size);
|
|
if(init_script_buf)
|
|
{
|
|
if( hxcfe_execScriptRam(hxcfe, init_script_buf, data_init_script->size) != HXCFE_NOERROR )
|
|
goto init_error;
|
|
|
|
free( init_script_buf );
|
|
}
|
|
|
|
#if defined(WIN32)
|
|
hxcfe_execScriptLine( hxcfe, "set SPSCAPS_LIB_NAME CAPSImg.dll" );
|
|
#elif __APPLE__
|
|
hxcfe_execScriptLine( hxcfe, "set SPSCAPS_LIB_NAME @rpath/CAPSImage.framework/CAPSImage,@rpath/CAPSImg.framework/CAPSImg" );
|
|
#else
|
|
hxcfe_execScriptLine( hxcfe, "set SPSCAPS_LIB_NAME libcapsimage.so.5,libcapsimage.so.5.1,libcapsimage.so" );
|
|
#endif
|
|
|
|
hxcfe_execScriptFile(hxcfe, "config.script");
|
|
|
|
savefilepath = hxcfe_getEnvVar( hxcfe, "UISTATE_SAVE_FILE", 0 );
|
|
if(savefilepath)
|
|
{
|
|
if(strlen(savefilepath))
|
|
{
|
|
hxcfe_execScriptFile(hxcfe, savefilepath);
|
|
}
|
|
else
|
|
{
|
|
hxcfe_execScriptLine( hxcfe, "set UISTATE_SAVE_FILE laststate.script" );
|
|
savefilepath = hxcfe_getEnvVar( hxcfe, "UISTATE_SAVE_FILE", 0 );
|
|
hxcfe_execScriptFile(hxcfe, savefilepath);
|
|
}
|
|
}
|
|
|
|
nb_loader = 0;
|
|
// Count how many static loaders we have.
|
|
while( staticplugins[nb_loader] )
|
|
{
|
|
nb_loader++;
|
|
}
|
|
|
|
nb_xml_loader = 0;
|
|
imgldr_ctx = hxcfe_imgInitLoader(hxcfe);
|
|
if( imgldr_ctx )
|
|
{
|
|
ret = staticplugins[nb_loader - 1](imgldr_ctx,GETNBSUBLOADER,&nb_xml_loader);
|
|
if( ret != HXCFE_NOERROR )
|
|
{
|
|
nb_xml_loader = 0;
|
|
hxcfe->hxc_printf(MSG_ERROR,"XML Loader unavailable...");
|
|
}
|
|
}
|
|
|
|
if( nb_loader )
|
|
{
|
|
hxcfe->image_handlers = (void*)calloc( 1, (nb_loader+nb_xml_loader+1) * sizeof(image_plugin) );
|
|
if( hxcfe->image_handlers )
|
|
{
|
|
plugin_ptr = (image_plugin*)hxcfe->image_handlers;
|
|
|
|
for( i = 0 ; i < nb_loader - 1; i++ )
|
|
{
|
|
plugin_ptr[i].infos_handler = staticplugins[i];
|
|
plugin_ptr[i].sub_id = 0;
|
|
plugin_ptr[i].flags = 0x00000000;
|
|
}
|
|
|
|
for( j = 0 ; j < nb_xml_loader; j++ )
|
|
{
|
|
plugin_ptr[i + j].infos_handler = staticplugins[nb_loader - 1];
|
|
plugin_ptr[i + j].sub_id = j + 1;
|
|
plugin_ptr[i + j].flags = IMAGE_LDR_DISABLED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( imgldr_ctx )
|
|
hxcfe_imgDeInitLoader(imgldr_ctx);
|
|
|
|
free( hxcfe );
|
|
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if( imgldr_ctx )
|
|
hxcfe_imgDeInitLoader(imgldr_ctx);
|
|
}
|
|
|
|
return hxcfe;
|
|
|
|
init_error:
|
|
|
|
free( hxcfe );
|
|
|
|
free( init_script_buf );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int32_t hxcfe_setOutputFunc( HXCFE* floppycontext, HXCFE_PRINTF_FUNC hxc_printf )
|
|
{
|
|
floppycontext->hxc_printf=hxc_printf;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
const char * hxcfe_getVersion(HXCFE* floppycontext)
|
|
{
|
|
return STR_FILE_VERSION2;
|
|
}
|
|
|
|
const char * hxcfe_getLicense(HXCFE* floppycontext)
|
|
{
|
|
if(floppycontext)
|
|
{
|
|
if(!floppycontext->license)
|
|
{
|
|
floppycontext->license = (char*)data_unpack(data_COPYING_FULL->data,data_COPYING_FULL->csize,0,data_COPYING_FULL->size + 1);
|
|
floppycontext->license[data_COPYING_FULL->size] = 0;
|
|
}
|
|
|
|
return (char*)floppycontext->license;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void hxcfe_deinit(HXCFE* hxcfe)
|
|
{
|
|
if( hxcfe )
|
|
{
|
|
hxcfe->hxc_printf(MSG_INFO_0,"Stopping HxCFloppyEmulator...");
|
|
|
|
hxcfe_deinitScript(hxcfe);
|
|
|
|
free( hxcfe->image_handlers );
|
|
|
|
free( hxcfe->license );
|
|
|
|
free( hxcfe );
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
static int32_t hxcfe_checkLoaderID( HXCFE_IMGLDR * imgldr_ctx, int32_t moduleID )
|
|
{
|
|
int i;
|
|
image_plugin* plugin_ptr;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
if( moduleID >= 0 )
|
|
{
|
|
i=0;
|
|
do
|
|
{
|
|
i++;
|
|
}while( plugin_ptr[i].infos_handler && i<moduleID);
|
|
|
|
if( !plugin_ptr[i].infos_handler )
|
|
{
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
else
|
|
{
|
|
return HXCFE_NOERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
}
|
|
|
|
int32_t hxcfe_imgGetNumberOfLoader( HXCFE_IMGLDR * imgldr_ctx )
|
|
{
|
|
int i;
|
|
image_plugin* plugin_ptr;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
i=0;
|
|
do
|
|
{
|
|
i++;
|
|
}while( plugin_ptr[i].infos_handler );
|
|
|
|
return i;
|
|
}
|
|
|
|
int32_t hxcfe_imgGetLoaderID( HXCFE_IMGLDR * imgldr_ctx, char * container )
|
|
{
|
|
int i;
|
|
int ret;
|
|
char * plugin_id;
|
|
image_plugin* plugin_ptr;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
ret=0;
|
|
i=0;
|
|
do
|
|
{
|
|
if( plugin_ptr[i].infos_handler )
|
|
{
|
|
ret = plugin_ptr[i].infos_handler(imgldr_ctx,GETPLUGINID,&plugin_id);
|
|
if((ret==HXCFE_NOERROR) && !strcmp(container,plugin_id))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}while( plugin_ptr[i].infos_handler );
|
|
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_DEBUG,"hxcfe_searchContainer : Plugin %s not found !",container);
|
|
|
|
return -1;
|
|
}
|
|
|
|
int32_t hxcfe_imgGetLoaderAccess( HXCFE_IMGLDR * imgldr_ctx, int32_t moduleID )
|
|
{
|
|
int ret;
|
|
plugins_ptr func_ptr;
|
|
image_plugin* plugin_ptr;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
ret = 0;
|
|
|
|
if(hxcfe_checkLoaderID(imgldr_ctx,moduleID)==HXCFE_NOERROR)
|
|
{
|
|
ret=plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if(ret==HXCFE_NOERROR)
|
|
{
|
|
imgldr_ctx->selected_id = moduleID;
|
|
imgldr_ctx->selected_subid = 0;
|
|
|
|
if(func_ptr.libLoad_DiskFile)
|
|
ret=ret | 0x01;
|
|
if(func_ptr.libWrite_DiskFile)
|
|
ret=ret | 0x02;
|
|
|
|
return ret;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Bad module ID : %x !",moduleID);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
const char* hxcfe_imgGetLoaderDesc( HXCFE_IMGLDR * imgldr_ctx, int32_t moduleID )
|
|
{
|
|
int ret;
|
|
plugins_ptr func_ptr;
|
|
char * desc;
|
|
image_plugin* plugin_ptr;
|
|
int sub_id;
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
if(hxcfe_checkLoaderID(imgldr_ctx,moduleID)==HXCFE_NOERROR)
|
|
{
|
|
ret = plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if(ret==HXCFE_NOERROR)
|
|
{
|
|
imgldr_ctx->selected_id = moduleID;
|
|
imgldr_ctx->selected_subid = 0;
|
|
|
|
if( !plugin_ptr[moduleID].sub_id)
|
|
{
|
|
plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETDESCRIPTION,&desc);
|
|
}
|
|
else
|
|
{
|
|
sub_id = plugin_ptr[moduleID].sub_id;
|
|
if( plugin_ptr[moduleID].infos_handler(imgldr_ctx,SELECTSUBLOADER,&sub_id) == HXCFE_NOERROR )
|
|
{
|
|
plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETDESCRIPTION,&desc);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Bad module ID : %x !",moduleID);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char* hxcfe_imgGetLoaderName( HXCFE_IMGLDR * imgldr_ctx, int32_t moduleID )
|
|
{
|
|
int ret;
|
|
plugins_ptr func_ptr;
|
|
char * desc;
|
|
image_plugin* plugin_ptr;
|
|
int sub_id;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
if(hxcfe_checkLoaderID(imgldr_ctx,moduleID)==HXCFE_NOERROR)
|
|
{
|
|
ret = plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if(ret==HXCFE_NOERROR)
|
|
{
|
|
imgldr_ctx->selected_id = moduleID;
|
|
imgldr_ctx->selected_subid = 0;
|
|
|
|
if( !plugin_ptr[moduleID].sub_id)
|
|
{
|
|
plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETPLUGINID,&desc);
|
|
}
|
|
else
|
|
{
|
|
sub_id = plugin_ptr[moduleID].sub_id;
|
|
if( plugin_ptr[moduleID].infos_handler(imgldr_ctx,SELECTSUBLOADER,&sub_id) == HXCFE_NOERROR )
|
|
{
|
|
plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETPLUGINID,&desc);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Bad module ID : %x !",moduleID);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char* hxcfe_imgGetLoaderExt( HXCFE_IMGLDR * imgldr_ctx, int32_t moduleID )
|
|
{
|
|
int ret;
|
|
plugins_ptr func_ptr;
|
|
char * desc;
|
|
image_plugin* plugin_ptr;
|
|
int sub_id;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
if(hxcfe_checkLoaderID(imgldr_ctx,moduleID)==HXCFE_NOERROR)
|
|
{
|
|
ret = plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if(ret==HXCFE_NOERROR)
|
|
{
|
|
imgldr_ctx->selected_id = moduleID;
|
|
imgldr_ctx->selected_subid = 0;
|
|
|
|
if( !plugin_ptr[moduleID].sub_id)
|
|
{
|
|
plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETEXTENSION,&desc);
|
|
}
|
|
else
|
|
{
|
|
sub_id = plugin_ptr[moduleID].sub_id;
|
|
if( plugin_ptr[moduleID].infos_handler(imgldr_ctx,SELECTSUBLOADER,&sub_id) == HXCFE_NOERROR )
|
|
{
|
|
plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETEXTENSION,&desc);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Bad module ID : %x !",moduleID);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_imgCheckFileCompatibility( HXCFE_IMGLDR * imgldr_ctx, HXCFE_IMGLDR_FILEINFOS * file_infos, char * loadername, char * fileext, int filesizemod)
|
|
{
|
|
char temp_ext[16];
|
|
int ret;
|
|
int i,j;
|
|
|
|
if(loadername)
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_DEBUG,"%s", loadername);
|
|
|
|
if( fileext )
|
|
{
|
|
j = 0;
|
|
do
|
|
{
|
|
memset(temp_ext,0,sizeof(temp_ext));
|
|
|
|
i = 0;
|
|
while ( i < sizeof(temp_ext) - 1 && fileext[j] != ',' && fileext[j] )
|
|
{
|
|
temp_ext[i] = fileext[j];
|
|
j++;
|
|
i++;
|
|
}
|
|
|
|
if(fileext[j] == ',')
|
|
j++;
|
|
|
|
ret = hxc_checkfileext( file_infos->path, temp_ext, SYS_PATH_TYPE );
|
|
}while(fileext[j] && !ret);
|
|
|
|
if( !ret )
|
|
return HXCFE_BADFILE;
|
|
}
|
|
|
|
if( filesizemod )
|
|
{
|
|
if( ( file_infos->file_size % filesizemod ) || (file_infos->file_size <= 0) )
|
|
{
|
|
return HXCFE_BADFILE;
|
|
}
|
|
}
|
|
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_DEBUG,"%s : %s is an %s file !", loadername, file_infos->path,fileext);
|
|
|
|
return HXCFE_VALIDFILE;
|
|
}
|
|
|
|
int32_t hxcfe_preloadImgInfos(HXCFE_IMGLDR * imgldr_ctx, char * imgname, HXCFE_IMGLDR_FILEINFOS * file_infos)
|
|
{
|
|
FILE *f;
|
|
struct stat img_stat;
|
|
|
|
memset(file_infos,0,sizeof(HXCFE_IMGLDR_FILEINFOS));
|
|
memset(&img_stat,0,sizeof(struct stat));
|
|
|
|
hxc_stat( imgname, &img_stat );
|
|
|
|
if(img_stat.st_mode&S_IFDIR)
|
|
file_infos->is_dir = 1;
|
|
else
|
|
file_infos->is_dir = 0;
|
|
|
|
file_infos->file_size = 0;
|
|
|
|
if(!file_infos->is_dir)
|
|
{
|
|
f = hxc_fopen(imgname,"rb");
|
|
if( f == NULL )
|
|
return HXCFE_ACCESSERROR;
|
|
|
|
file_infos->file_size = hxc_fgetsize(f);
|
|
|
|
hxc_fread(&file_infos->file_header,sizeof(file_infos->file_header),f);
|
|
|
|
hxc_fclose(f);
|
|
}
|
|
|
|
strncpy(file_infos->file_extension, hxc_getfilenameext( imgname, 0, SYS_PATH_TYPE ), sizeof(file_infos->file_extension)-1);
|
|
file_infos->file_extension[sizeof(file_infos->file_extension)-1] = 0;
|
|
|
|
strncpy(file_infos->path, imgname, sizeof(file_infos->path));
|
|
file_infos->path[sizeof(file_infos->path)-1] = 0;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_imgAutoSetectLoader( HXCFE_IMGLDR * imgldr_ctx, char* imgname, int32_t moduleID )
|
|
{
|
|
int i;
|
|
int ret;
|
|
plugins_ptr func_ptr;
|
|
HXCFE* hxcfe;
|
|
image_plugin* plugin_ptr;
|
|
HXCFE_IMGLDR_FILEINFOS file_infos;
|
|
|
|
ret = HXCFE_BADPARAMETER;
|
|
|
|
if( imgldr_ctx )
|
|
{
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
hxcfe = imgldr_ctx->hxcfe;
|
|
|
|
hxcfe->hxc_printf(MSG_INFO_0,"Checking %s",imgname);
|
|
|
|
ret = hxcfe_preloadImgInfos(imgldr_ctx, imgname, &file_infos);
|
|
if(ret != HXCFE_NOERROR)
|
|
return ret;
|
|
|
|
ret = HXCFE_BADPARAMETER;
|
|
|
|
i = moduleID;
|
|
do
|
|
{
|
|
if(plugin_ptr[i].infos_handler && !(plugin_ptr[i].flags & IMAGE_LDR_DISABLED) )
|
|
{
|
|
ret = plugin_ptr[i].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if( ret == HXCFE_NOERROR )
|
|
{
|
|
if(func_ptr.libIsValidDiskFile)
|
|
{
|
|
ret = func_ptr.libIsValidDiskFile(imgldr_ctx,&file_infos);
|
|
if(ret == HXCFE_VALIDFILE)
|
|
{
|
|
hxcfe->hxc_printf(MSG_INFO_0,"File loader found : %s (%s)",hxcfe_imgGetLoaderName(imgldr_ctx,i),hxcfe_imgGetLoaderDesc(imgldr_ctx,i));
|
|
|
|
return i;
|
|
}
|
|
else
|
|
{
|
|
hxcfe->hxc_printf(MSG_DEBUG,"libIsValidDiskFile n%d return %d",i,ret);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}while( plugin_ptr[i].infos_handler );
|
|
|
|
hxcfe->hxc_printf(MSG_ERROR,"No loader support the file %s !",imgname);
|
|
|
|
ret = HXCFE_UNSUPPORTEDFILE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int32_t hxcfe_imgSetProgressCallback( HXCFE_IMGLDR * imgldr_ctx, HXCFE_IMGLDRPROGRESSOUT_FUNC progress_func, void * userdata )
|
|
{
|
|
if(imgldr_ctx)
|
|
{
|
|
if(progress_func)
|
|
{
|
|
imgldr_ctx->progress_userdata = userdata;
|
|
imgldr_ctx->hxc_setprogress = progress_func;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_imgCallProgressCallback( HXCFE_IMGLDR * imgldr_ctx, int32_t cur, int32_t max )
|
|
{
|
|
if(imgldr_ctx)
|
|
{
|
|
if(imgldr_ctx->hxc_setprogress)
|
|
{
|
|
imgldr_ctx->hxc_setprogress(cur,max,imgldr_ctx->progress_userdata);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
HXCFE_IMGLDR * hxcfe_imgInitLoader(HXCFE * hxcfe)
|
|
{
|
|
HXCFE_IMGLDR * imgldr_ctx;
|
|
|
|
imgldr_ctx = calloc( 1, sizeof(HXCFE_IMGLDR));
|
|
if(imgldr_ctx)
|
|
{
|
|
imgldr_ctx->hxcfe = hxcfe;
|
|
imgldr_ctx->hxc_setprogress=&dummy_progress;
|
|
}
|
|
|
|
return imgldr_ctx;
|
|
}
|
|
|
|
void hxcfe_imgDeInitLoader(HXCFE_IMGLDR * imgldr_ctx)
|
|
{
|
|
free( imgldr_ctx );
|
|
|
|
return;
|
|
}
|
|
|
|
HXCFE_FLOPPY * hxcfe_imgLoadEx( HXCFE_IMGLDR * imgldr_ctx, char* imgname, int32_t moduleID, int32_t * err_ret, void * parameters )
|
|
{
|
|
int ret;
|
|
HXCFE* hxcfe;
|
|
HXCFE_FLOPPY * newfloppy;
|
|
plugins_ptr func_ptr;
|
|
image_plugin* plugin_ptr;
|
|
HXCFE_IMGLDR_FILEINFOS file_infos;
|
|
|
|
newfloppy = 0;
|
|
|
|
if(imgldr_ctx)
|
|
{
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
hxcfe = imgldr_ctx->hxcfe;
|
|
|
|
hxcfe->hxc_printf(MSG_INFO_0,"Loading %s",imgname);
|
|
|
|
ret = hxcfe_preloadImgInfos(imgldr_ctx, imgname, &file_infos);
|
|
if(ret != HXCFE_NOERROR)
|
|
{
|
|
if(err_ret)
|
|
*err_ret = ret;
|
|
return 0;
|
|
}
|
|
|
|
if( hxcfe_checkLoaderID(imgldr_ctx,moduleID) == HXCFE_NOERROR )
|
|
{
|
|
ret = plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if( ret == HXCFE_NOERROR )
|
|
{
|
|
ret = func_ptr.libIsValidDiskFile(imgldr_ctx,&file_infos);
|
|
if( ret == HXCFE_VALIDFILE )
|
|
{
|
|
newfloppy = calloc( 1, sizeof(HXCFE_FLOPPY) );
|
|
if(newfloppy)
|
|
{
|
|
hxcfe->hxc_printf(MSG_INFO_0,"file loader found!");
|
|
ret = func_ptr.libLoad_DiskFile(imgldr_ctx,newfloppy,imgname,parameters);
|
|
if(ret != HXCFE_NOERROR)
|
|
{
|
|
free( newfloppy );
|
|
newfloppy = NULL;
|
|
}
|
|
|
|
if(err_ret)
|
|
*err_ret = ret;
|
|
}
|
|
return newfloppy;
|
|
}
|
|
else
|
|
{
|
|
hxcfe->hxc_printf(MSG_ERROR,"%s refuse the file %s (%d)!",hxcfe_imgGetLoaderName(imgldr_ctx,moduleID),imgname,ret);
|
|
|
|
if(err_ret)
|
|
*err_ret=ret;
|
|
|
|
return newfloppy;
|
|
}
|
|
}
|
|
}
|
|
|
|
hxcfe->hxc_printf(MSG_ERROR,"Bad plugin ID : 0x%x",moduleID);
|
|
|
|
ret = HXCFE_BADPARAMETER;
|
|
if(err_ret)
|
|
*err_ret = ret;
|
|
|
|
}
|
|
return newfloppy;
|
|
|
|
}
|
|
|
|
HXCFE_FLOPPY * hxcfe_imgLoad(HXCFE_IMGLDR * imgldr_ctx, char* imgname, int32_t moduleID, int32_t * err_ret )
|
|
{
|
|
return hxcfe_imgLoadEx(imgldr_ctx,imgname,moduleID,err_ret,0);
|
|
}
|
|
|
|
int32_t hxcfe_imgUnload( HXCFE_IMGLDR * imgldr_ctx, HXCFE_FLOPPY * floppydisk )
|
|
{
|
|
return hxcfe_floppyUnload( imgldr_ctx->hxcfe, floppydisk );
|
|
}
|
|
|
|
int32_t hxcfe_imgExport( HXCFE_IMGLDR * imgldr_ctx, HXCFE_FLOPPY * newfloppy, char* imgname, int32_t moduleID )
|
|
{
|
|
int ret;
|
|
plugins_ptr func_ptr;
|
|
image_plugin* plugin_ptr;
|
|
|
|
plugin_ptr = (image_plugin*)imgldr_ctx->hxcfe->image_handlers;
|
|
|
|
if(hxcfe_checkLoaderID(imgldr_ctx,moduleID)==HXCFE_NOERROR)
|
|
{
|
|
ret=plugin_ptr[moduleID].infos_handler(imgldr_ctx->hxcfe,GETFUNCPTR,&func_ptr);
|
|
if(ret==HXCFE_NOERROR)
|
|
{
|
|
if(func_ptr.libWrite_DiskFile)
|
|
{
|
|
ret=func_ptr.libWrite_DiskFile(imgldr_ctx,newfloppy,imgname,0);
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"No export support in %s!",hxcfe_imgGetLoaderName(imgldr_ctx,moduleID) );
|
|
return HXCFE_UNSUPPORTEDFILE;
|
|
}
|
|
}
|
|
}
|
|
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Bad plugin ID : 0x%x",moduleID);
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
int32_t hxcfe_freeFloppy( HXCFE* floppycontext, HXCFE_FLOPPY * floppydisk )
|
|
{
|
|
int i,j;
|
|
|
|
if(floppydisk)
|
|
{
|
|
if( floppydisk->tracks )
|
|
{
|
|
for(j=0;j<floppydisk->floppyNumberOfTrack;j++)
|
|
{
|
|
if( floppydisk->tracks[j] )
|
|
{
|
|
if( floppydisk->tracks[j]->sides )
|
|
{
|
|
for(i=0;i<floppydisk->floppyNumberOfSide;i++)
|
|
{
|
|
hxcfe_freeSide(floppycontext,floppydisk->tracks[j]->sides[i]);
|
|
floppydisk->tracks[j]->sides[i] = NULL;
|
|
}
|
|
|
|
free( floppydisk->tracks[j]->sides );
|
|
floppydisk->tracks[j]->sides = NULL;
|
|
}
|
|
|
|
free(floppydisk->tracks[j]);
|
|
floppydisk->tracks[j] = NULL;
|
|
}
|
|
}
|
|
free(floppydisk->tracks);
|
|
floppydisk->tracks = NULL;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_floppyUnload( HXCFE* floppycontext, HXCFE_FLOPPY * floppydisk )
|
|
{
|
|
hxcfe_freeFloppy( floppycontext, floppydisk );
|
|
|
|
free( floppydisk );
|
|
|
|
return 0;
|
|
}
|
|
|
|
HXCFE_FLOPPY * hxcfe_floppyDuplicate( HXCFE* floppycontext, HXCFE_FLOPPY * floppydisk )
|
|
{
|
|
int i,j;
|
|
HXCFE_FLOPPY * fp;
|
|
|
|
fp = NULL;
|
|
if(floppydisk)
|
|
{
|
|
fp = malloc(sizeof(HXCFE_FLOPPY));
|
|
if(fp)
|
|
{
|
|
memcpy(fp,floppydisk,sizeof(HXCFE_FLOPPY));
|
|
|
|
fp->tracks = (HXCFE_CYLINDER**)malloc(sizeof(HXCFE_CYLINDER*)*fp->floppyNumberOfTrack);
|
|
if(fp->tracks)
|
|
{
|
|
for(j=0;j<fp->floppyNumberOfTrack;j++)
|
|
{
|
|
fp->tracks[j] = (HXCFE_CYLINDER*)malloc(sizeof(HXCFE_CYLINDER));
|
|
if( fp->tracks[j] )
|
|
{
|
|
memcpy( fp->tracks[j], floppydisk->tracks[j], sizeof(HXCFE_CYLINDER) );
|
|
|
|
fp->tracks[j]->sides = (HXCFE_SIDE**)calloc( 1, sizeof(HXCFE_SIDE*)*fp->tracks[j]->number_of_side );
|
|
if(fp->tracks[j]->sides)
|
|
{
|
|
for(i=0;i<fp->tracks[j]->number_of_side;i++)
|
|
{
|
|
fp->tracks[j]->sides[i] = hxcfe_duplicateSide( floppycontext, floppydisk->tracks[j]->sides[i] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return fp;
|
|
}
|
|
|
|
int32_t hxcfe_floppySectorBySectorCopy( HXCFE* floppycontext, HXCFE_FLOPPY * dest_floppy, HXCFE_FLOPPY * src_floppy, int dest_format_ref )
|
|
{
|
|
int i,j,l,len;
|
|
int32_t fdcstatus;
|
|
HXCFE_SECTORACCESS* ref_sect_access;
|
|
HXCFE_SECTORACCESS* src_sect_access;
|
|
HXCFE_SECTORACCESS* new_sect_access;
|
|
HXCFE_SECTCFG* sect_ref;
|
|
HXCFE_FLOPPY * ref_floppy;
|
|
|
|
unsigned char * sect_buf;
|
|
int types[]={ISOIBM_MFM_ENCODING,ISOIBM_FM_ENCODING,AMIGA_MFM_ENCODING,-1};
|
|
int type_index;
|
|
char tag_string[64+1];
|
|
int error_tag_value;
|
|
|
|
if(dest_format_ref)
|
|
{
|
|
ref_floppy = hxcfe_floppyDuplicate( floppycontext, dest_floppy );
|
|
}
|
|
else
|
|
{
|
|
ref_floppy = hxcfe_floppyDuplicate( floppycontext, src_floppy );
|
|
}
|
|
|
|
if(!ref_floppy)
|
|
return HXCFE_BADPARAMETER;
|
|
|
|
ref_sect_access = hxcfe_initSectorAccess( floppycontext, ref_floppy );
|
|
if(!ref_sect_access)
|
|
return HXCFE_BADPARAMETER;
|
|
|
|
new_sect_access = hxcfe_initSectorAccess( floppycontext, dest_floppy );
|
|
if(!new_sect_access)
|
|
return HXCFE_BADPARAMETER;
|
|
|
|
src_sect_access = hxcfe_initSectorAccess( floppycontext, src_floppy );
|
|
if(!src_sect_access)
|
|
return HXCFE_BADPARAMETER;
|
|
|
|
type_index = 0;
|
|
|
|
error_tag_value = hxcfe_getEnvVarValue( floppycontext, "SECTORBYSECTORCOPY_SECTOR_ERROR_TAG" );
|
|
|
|
while(types[type_index] != -1)
|
|
{
|
|
for(i=0;i<ref_floppy->floppyNumberOfTrack;i++)
|
|
{
|
|
for(j=0;j<ref_floppy->floppyNumberOfSide;j++)
|
|
{
|
|
hxcfe_resetSearchTrackPosition(ref_sect_access);
|
|
do
|
|
{
|
|
sect_ref = hxcfe_getNextSector( ref_sect_access, i, j, types[type_index]);
|
|
if(sect_ref)
|
|
{
|
|
hxcfe_readSectorData( src_sect_access, i, j, sect_ref->sector, 1, sect_ref->sectorsize, types[type_index], sect_ref->input_data, &fdcstatus );
|
|
|
|
sect_buf = NULL;
|
|
if(fdcstatus != FDC_NOERROR)
|
|
{
|
|
switch(fdcstatus)
|
|
{
|
|
case FDC_BAD_DATA_CRC:
|
|
snprintf(tag_string,sizeof(tag_string)-1,"<ERROR DATA_CRC T:%.3d H:%c S:%.3d>",i,'0'+(j&1),sect_ref->sector);
|
|
break;
|
|
case FDC_NO_DATA:
|
|
snprintf(tag_string,sizeof(tag_string)-1,"<ERROR NO_DATA T:%.3d H:%c S:%.3d>",i,'0'+(j&1),sect_ref->sector);
|
|
break;
|
|
case FDC_SECTOR_NOT_FOUND:
|
|
snprintf(tag_string,sizeof(tag_string)-1,"<ERROR NOTFOUND T:%.3d H:%c S:%.3d>",i,'0'+(j&1),sect_ref->sector);
|
|
break;
|
|
case FDC_ACCESS_ERROR:
|
|
snprintf(tag_string,sizeof(tag_string)-1,"<ERROR ACCESS T:%.3d H:%c S:%.3d>",i,'0'+(j&1),sect_ref->sector);
|
|
break;
|
|
}
|
|
|
|
floppycontext->hxc_printf(MSG_WARNING,"Source file sector error : %s", tag_string );
|
|
|
|
if(sect_ref->sectorsize > 0)
|
|
{
|
|
sect_buf = malloc(sect_ref->sectorsize + 1);
|
|
if(sect_buf)
|
|
{
|
|
if(error_tag_value >= 0)
|
|
memset(sect_buf,error_tag_value,sect_ref->sectorsize + 1);
|
|
else
|
|
memset(sect_buf,0,sect_ref->sectorsize + 1);
|
|
|
|
if(error_tag_value == -1)
|
|
{
|
|
len = strlen(tag_string);
|
|
if(len)
|
|
{
|
|
for(l=0;l<sect_ref->sectorsize / len;l++)
|
|
{
|
|
strcat((char*)sect_buf,tag_string);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(sect_buf)
|
|
{
|
|
if(error_tag_value != -2)
|
|
hxcfe_writeSectorData( new_sect_access, i, j, sect_ref->sector, 1, sect_ref->sectorsize, types[type_index], sect_buf, &fdcstatus );
|
|
|
|
free(sect_buf);
|
|
}
|
|
else
|
|
{
|
|
hxcfe_writeSectorData( new_sect_access, i, j, sect_ref->sector, 1, sect_ref->sectorsize, types[type_index], sect_ref->input_data, &fdcstatus );
|
|
}
|
|
|
|
hxcfe_freeSectorConfigData( 0, sect_ref );
|
|
}
|
|
}while(sect_ref);
|
|
}
|
|
}
|
|
|
|
type_index++;
|
|
}
|
|
|
|
hxcfe_floppyUnload( floppycontext, ref_floppy );
|
|
|
|
hxcfe_deinitSectorAccess( ref_sect_access );
|
|
hxcfe_deinitSectorAccess( new_sect_access );
|
|
hxcfe_deinitSectorAccess( src_sect_access );
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
int32_t hxcfe_floppyGetSetParams( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy, uint8_t dir, uint16_t param, void * value )
|
|
{
|
|
int ret;
|
|
|
|
ret=HXCFE_BADPARAMETER;
|
|
switch(dir)
|
|
{
|
|
case GET:
|
|
switch(param)
|
|
{
|
|
case DOUBLESTEP:
|
|
*((unsigned char*)value)=newfloppy->double_step;
|
|
ret=HXCFE_NOERROR;
|
|
break;
|
|
|
|
case INTERFACEMODE:
|
|
*((unsigned short*)value)=newfloppy->floppyiftype;
|
|
ret=HXCFE_NOERROR;
|
|
break;
|
|
}
|
|
break;
|
|
case SET:
|
|
switch(param)
|
|
{
|
|
case DOUBLESTEP:
|
|
if(*(unsigned char*)value)
|
|
{
|
|
newfloppy->double_step=0xFF;
|
|
}
|
|
else
|
|
{
|
|
newfloppy->double_step=0x00;
|
|
|
|
}
|
|
ret=HXCFE_NOERROR;
|
|
break;
|
|
|
|
case INTERFACEMODE:
|
|
newfloppy->floppyiftype=*(unsigned short*)value;
|
|
ret=HXCFE_NOERROR;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int32_t hxcfe_floppyGetInterfaceMode( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy )
|
|
{
|
|
return newfloppy->floppyiftype;
|
|
}
|
|
|
|
int32_t hxcfe_floppySetInterfaceMode( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy, int32_t ifmode )
|
|
{
|
|
|
|
if(hxcfe_getFloppyInterfaceModeName(floppycontext,ifmode))
|
|
{
|
|
newfloppy->floppyiftype=ifmode;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
int32_t hxcfe_floppyGetDoubleStep( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy )
|
|
{
|
|
return newfloppy->double_step;
|
|
}
|
|
|
|
int32_t hxcfe_floppySetDoubleStep( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy, int32_t doublestep )
|
|
{
|
|
newfloppy->double_step=doublestep;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
uint32_t hxcfe_floppyGetFlags( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy )
|
|
{
|
|
return newfloppy->flags;
|
|
}
|
|
|
|
int32_t hxcfe_floppySetFlags( HXCFE* floppycontext, HXCFE_FLOPPY * newfloppy, uint32_t flags )
|
|
{
|
|
newfloppy->flags = flags;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int libGetPluginInfo( HXCFE_IMGLDR * imgldr_ctx, uint32_t infotype, void * returnvalue, const char * pluginid, const char * plugindesc, plugins_ptr * pluginfunc, const char * fileext )
|
|
{
|
|
if(imgldr_ctx)
|
|
{
|
|
if(returnvalue)
|
|
{
|
|
switch(infotype)
|
|
{
|
|
case GETPLUGINID:
|
|
*(char**)(returnvalue)=(char*)pluginid;
|
|
break;
|
|
|
|
case GETDESCRIPTION:
|
|
*(char**)(returnvalue)=(char*)plugindesc;
|
|
break;
|
|
|
|
case GETFUNCPTR:
|
|
memcpy(returnvalue,pluginfunc,sizeof(plugins_ptr));
|
|
break;
|
|
|
|
case GETEXTENSION:
|
|
*(char**)(returnvalue)=(char*)fileext;
|
|
break;
|
|
|
|
default:
|
|
return HXCFE_BADPARAMETER;
|
|
break;
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
}
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
HXCFE_FLPGEN* hxcfe_initFloppy( HXCFE* floppycontext, int32_t nb_of_track, int32_t nb_of_side )
|
|
{
|
|
HXCFE_FLPGEN* fb_ctx;
|
|
int i;
|
|
|
|
fb_ctx = 0;
|
|
|
|
floppycontext->hxc_printf(MSG_DEBUG,"hxcfe_init_floppy : floppy builder init");
|
|
|
|
if(( nb_of_track && (nb_of_track<=256)) && ((nb_of_side>=1) && (nb_of_side<=2) ) )
|
|
{
|
|
fb_ctx = (HXCFE_FLPGEN*)calloc( 1, sizeof(HXCFE_FLPGEN) );
|
|
if( !fb_ctx )
|
|
goto alloc_error;
|
|
|
|
fb_ctx->floppycontext = floppycontext;
|
|
|
|
fb_ctx->floppydisk = (HXCFE_FLOPPY*)calloc( 1, sizeof(HXCFE_FLOPPY) );
|
|
if(!fb_ctx->floppydisk)
|
|
goto alloc_error;
|
|
|
|
fb_ctx->floppydisk->floppyBitRate=DEFAULT_DD_BITRATE;
|
|
fb_ctx->floppydisk->double_step=0;
|
|
fb_ctx->floppydisk->floppyiftype=GENERIC_SHUGART_DD_FLOPPYMODE;
|
|
fb_ctx->floppydisk->floppyNumberOfTrack=nb_of_track;
|
|
fb_ctx->floppydisk->floppyNumberOfSide=nb_of_side;
|
|
fb_ctx->floppydisk->floppySectorPerTrack=-1;
|
|
|
|
fb_ctx->floppydisk->tracks = (HXCFE_CYLINDER**)calloc( 1, sizeof(HXCFE_CYLINDER*)*fb_ctx->floppydisk->floppyNumberOfTrack );
|
|
if(!fb_ctx->floppydisk->tracks)
|
|
goto alloc_error;
|
|
|
|
fb_ctx->fb_stack_pointer=0;
|
|
|
|
fb_ctx->fb_stack = (fb_track_state*)calloc( 1, sizeof(fb_track_state)*STACK_SIZE );
|
|
if(!fb_ctx->fb_stack)
|
|
goto alloc_error;
|
|
|
|
fb_ctx->fb_stack[0].interleave=1;
|
|
fb_ctx->fb_stack[0].rpm=300;
|
|
|
|
fb_ctx->fb_stack[0].forced_side_id = -1;
|
|
|
|
fb_ctx->fb_stack[0].sectors_size = 512;
|
|
|
|
for(i=0;i<MAX_NUMBER_OF_INDEX;i++)
|
|
{
|
|
fb_ctx->fb_stack[0].indexlen[i] = 0;
|
|
fb_ctx->fb_stack[0].indexpos[i] = 0;
|
|
}
|
|
|
|
fb_ctx->fb_stack[0].indexlen[0] = 2500;
|
|
fb_ctx->fb_stack[0].indexpos[0] = -2500;
|
|
fb_ctx->fb_stack[0].sectorunderindex=0;
|
|
|
|
fb_ctx->fb_stack[0].numberofsector = 0;
|
|
fb_ctx->fb_stack[0].numberofsector_min = 0;
|
|
fb_ctx->fb_stack[0].start_sector_id = 1;
|
|
|
|
fb_ctx->fb_stack[0].bitrate=250000;
|
|
fb_ctx->fb_stack[0].sectorconfig.bitrate=fb_ctx->fb_stack[0].bitrate;
|
|
fb_ctx->fb_stack[0].sectorconfig.fill_byte=0xF6;
|
|
fb_ctx->fb_stack[0].sectorconfig.gap3=255;
|
|
fb_ctx->fb_stack[0].sectorconfig.sectorsize=512;
|
|
fb_ctx->fb_stack[0].sectorconfig.trackencoding=IBMFORMAT_DD;
|
|
fb_ctx->fb_stack[0].type = IBMFORMAT_DD;
|
|
|
|
fb_ctx->fb_stack[0].sc_stack[0].bitrate = 250000;
|
|
fb_ctx->fb_stack[0].sc_stack[0].fill_byte = 0xF6;
|
|
fb_ctx->fb_stack[0].sc_stack[0].gap3 = 255;
|
|
fb_ctx->fb_stack[0].sc_stack[0].sectorsize = 512;
|
|
fb_ctx->fb_stack[0].sc_stack[0].trackencoding=IBMFORMAT_DD;
|
|
}
|
|
|
|
return fb_ctx;
|
|
|
|
alloc_error:
|
|
floppycontext->hxc_printf(MSG_ERROR,"hxcfe_init_floppy : malloc error");
|
|
|
|
if(fb_ctx)
|
|
{
|
|
if(fb_ctx->floppydisk)
|
|
{
|
|
free( fb_ctx->floppydisk->tracks );
|
|
|
|
free( fb_ctx->floppydisk );
|
|
}
|
|
|
|
free( fb_ctx->fb_stack );
|
|
|
|
free( fb_ctx );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getNumberOfTrack( HXCFE* floppycontext, HXCFE_FLOPPY *fp )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->floppyNumberOfTrack;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getNumberOfSide( HXCFE* floppycontext, HXCFE_FLOPPY *fp )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->floppyNumberOfSide;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_setNumberOfTrack ( HXCFE_FLPGEN* fb_ctx, int32_t numberoftrack )
|
|
{
|
|
HXCFE_CYLINDER ** tmptracks;
|
|
int tmpfloppyNumberOfTrack;
|
|
|
|
tmptracks = 0;
|
|
tmpfloppyNumberOfTrack = 0;
|
|
|
|
if( fb_ctx->floppydisk->tracks )
|
|
{
|
|
tmptracks = fb_ctx->floppydisk->tracks;
|
|
tmpfloppyNumberOfTrack = fb_ctx->floppydisk->floppyNumberOfTrack;
|
|
}
|
|
|
|
fb_ctx->floppydisk->floppyNumberOfTrack = numberoftrack;
|
|
fb_ctx->floppydisk->tracks = (HXCFE_CYLINDER**)calloc( 1, sizeof(HXCFE_CYLINDER*)*fb_ctx->floppydisk->floppyNumberOfTrack);
|
|
if( !fb_ctx->floppydisk->tracks)
|
|
{
|
|
return HXCFE_INTERNALERROR;
|
|
}
|
|
|
|
if(tmptracks)
|
|
{
|
|
if ( tmpfloppyNumberOfTrack < numberoftrack )
|
|
{
|
|
memcpy(fb_ctx->floppydisk->tracks,tmptracks,sizeof(HXCFE_CYLINDER*)*tmpfloppyNumberOfTrack);
|
|
}
|
|
else
|
|
{
|
|
memcpy(fb_ctx->floppydisk->tracks,tmptracks,sizeof(HXCFE_CYLINDER*)*numberoftrack);
|
|
}
|
|
|
|
free( tmptracks );
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setNumberOfSide ( HXCFE_FLPGEN* fb_ctx, int32_t numberofside )
|
|
{
|
|
fb_ctx->floppydisk->floppyNumberOfSide = numberofside;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setNumberOfSector ( HXCFE_FLPGEN* fb_ctx, int32_t numberofsector )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].numberofsector_min = numberofsector;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setTrackPreGap ( HXCFE_FLPGEN* fb_ctx, int32_t pregap )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].pregap = pregap;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_pushTrack ( HXCFE_FLPGEN* fb_ctx, uint32_t rpm, int32_t number, int32_t side, int32_t type )
|
|
{
|
|
fb_track_state * cur_track;
|
|
unsigned char * data_to_realloc;
|
|
int i;
|
|
|
|
if(fb_ctx->fb_stack_pointer<(STACK_SIZE-1))
|
|
{
|
|
fb_ctx->fb_stack_pointer++;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
memcpy(&fb_ctx->fb_stack[fb_ctx->fb_stack_pointer],&fb_ctx->fb_stack[fb_ctx->fb_stack_pointer-1],sizeof(fb_track_state));
|
|
|
|
i = 0;
|
|
while( i < fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].numberofsector )
|
|
{
|
|
if ( cur_track->sectortab[i].input_data )
|
|
{
|
|
data_to_realloc = cur_track->sectortab[i].input_data;
|
|
|
|
cur_track->sectortab[i].input_data = (unsigned char * )malloc(cur_track->sectortab[i].sectorsize);
|
|
if(cur_track->sectortab[i].input_data)
|
|
memcpy(cur_track->sectortab[i].input_data,data_to_realloc,cur_track->sectortab[i].sectorsize);
|
|
|
|
free( data_to_realloc );
|
|
}
|
|
i++;
|
|
}
|
|
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].rpm = rpm;
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].side_number = side;
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].track_number = number;
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].type = type;
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sc_stack[fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sc_stack_pointer].trackencoding = type;
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sectorconfig.trackencoding = type;
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].numberofsector = 0;
|
|
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sc_stack_pointer = 0;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
int32_t hxcfe_pushSector ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
if( cur_track->sc_stack_pointer < (STACK_SIZE-1) )
|
|
{
|
|
cur_track->sc_stack_pointer++;
|
|
memcpy(&cur_track->sc_stack[cur_track->sc_stack_pointer],&cur_track->sc_stack[cur_track->sc_stack_pointer-1],sizeof(HXCFE_SECTCFG));
|
|
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].sector++;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
return HXCFE_INTERNALERROR;
|
|
}
|
|
|
|
int32_t hxcfe_popSector ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
if( cur_track->numberofsector < (NUMBEROFSECTOR_MAX-1) )
|
|
{
|
|
memcpy(&cur_track->sectortab[cur_track->numberofsector],&cur_track->sc_stack[cur_track->sc_stack_pointer],sizeof(HXCFE_SECTCFG) );
|
|
cur_track->numberofsector++;
|
|
if(cur_track->numberofsector_min < cur_track->numberofsector )
|
|
cur_track->numberofsector_min = cur_track->numberofsector;
|
|
|
|
memset(&cur_track->sc_stack[cur_track->sc_stack_pointer],0,sizeof(HXCFE_SECTCFG));
|
|
|
|
if( cur_track->sc_stack_pointer )
|
|
{
|
|
cur_track->sc_stack_pointer--;
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
return HXCFE_INTERNALERROR;
|
|
}
|
|
|
|
int32_t hxcfe_pushTrackPFS ( HXCFE_FLPGEN* fb_ctx, int32_t number, int32_t side )
|
|
{
|
|
return hxcfe_pushTrack (fb_ctx,fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].rpm,number,side,fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].type);
|
|
}
|
|
|
|
int32_t hxcfe_setTrackBitrate ( HXCFE_FLPGEN* fb_ctx, int32_t bitrate )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
cur_track->bitrate = bitrate;
|
|
cur_track->sectorconfig.bitrate = bitrate;
|
|
cur_track->sc_stack[fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sc_stack_pointer].bitrate = bitrate;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setTrackType( HXCFE_FLPGEN* fb_ctx, int32_t type )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
cur_track->type = type;
|
|
cur_track->sectorconfig.trackencoding = type;
|
|
cur_track->sc_stack[fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sc_stack_pointer].trackencoding = type;
|
|
|
|
return HXCFE_NOERROR;
|
|
|
|
}
|
|
|
|
int32_t hxcfe_setTrackInterleave ( HXCFE_FLPGEN* fb_ctx, int32_t interleave )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].interleave = interleave;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorSize( HXCFE_FLPGEN* fb_ctx, int32_t size )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sectors_size = size;
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].sectorsize = size;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setTrackSkew ( HXCFE_FLPGEN* fb_ctx, int32_t skew )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].skew = skew;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSideSkew ( HXCFE_FLPGEN* fb_ctx, int32_t skew )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].side_skew = skew;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setIndexPosition ( HXCFE_FLPGEN* fb_ctx, int32_t index_number, int32_t position, int32_t allowsector )
|
|
{
|
|
if(index_number < MAX_NUMBER_OF_INDEX)
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].indexpos[index_number] = position;
|
|
}
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setIndexLength ( HXCFE_FLPGEN* fb_ctx, int32_t index_number, int32_t Length )
|
|
{
|
|
if(index_number < MAX_NUMBER_OF_INDEX)
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].indexlen[index_number] = Length;
|
|
}
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorData( HXCFE_FLPGEN* fb_ctx, uint8_t * buffer, int32_t size )
|
|
{
|
|
fb_track_state * cur_track;
|
|
HXCFE_SECTCFG * cur_sector;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_sector = &cur_track->sc_stack[cur_track->sc_stack_pointer];
|
|
|
|
free( cur_sector->input_data );
|
|
cur_sector->input_data = NULL;
|
|
|
|
free( cur_sector->weak_bits_mask );
|
|
cur_sector->weak_bits_mask = NULL;
|
|
|
|
if(buffer)
|
|
{
|
|
cur_sector->input_data = malloc(size);
|
|
if( cur_sector->input_data )
|
|
{
|
|
memcpy(cur_sector->input_data,buffer,size);
|
|
}
|
|
else
|
|
{
|
|
return HXCFE_INTERNALERROR;
|
|
}
|
|
}
|
|
|
|
cur_sector->sectorsize = size;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_addSector ( HXCFE_FLPGEN* fb_ctx, int32_t sectornumber, int32_t side, int32_t track, uint8_t * buffer, int32_t size )
|
|
{
|
|
hxcfe_pushSector (fb_ctx);
|
|
|
|
hxcfe_setSectorTrackID(fb_ctx,track);
|
|
hxcfe_setSectorHeadID(fb_ctx,side);
|
|
hxcfe_setSectorID(fb_ctx,sectornumber);
|
|
|
|
hxcfe_setSectorData(fb_ctx,buffer,size);
|
|
|
|
hxcfe_popSector (fb_ctx);
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_addSectors( HXCFE_FLPGEN* fb_ctx, int32_t side, int32_t track, uint8_t * trackdata, int32_t buffersize, int32_t numberofsectors )
|
|
{
|
|
int i,ret;
|
|
int startsectorid,sectorsize;
|
|
|
|
if(fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].numberofsector<0x400)
|
|
{
|
|
startsectorid = fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].start_sector_id;
|
|
sectorsize = fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sectors_size;
|
|
|
|
for(i = 0; i < numberofsectors ; i++)
|
|
{
|
|
if(trackdata)
|
|
ret = hxcfe_addSector(fb_ctx,startsectorid + i,side,track,&trackdata[i*sectorsize],sectorsize);
|
|
else
|
|
ret = hxcfe_addSector(fb_ctx,startsectorid + i,side,track,0,sectorsize);
|
|
|
|
if(ret != HXCFE_NOERROR)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorSizeID ( HXCFE_FLPGEN* fb_ctx, int32_t sectorsizeid )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].use_alternate_sector_size_id=0xFF;
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].alternate_sector_size_id=sectorsizeid;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setStartSectorID( HXCFE_FLPGEN* fb_ctx, int32_t startsectorid )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].start_sector_id = startsectorid;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorBitrate ( HXCFE_FLPGEN* fb_ctx, int32_t bitrate )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].bitrate=bitrate;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorFill ( HXCFE_FLPGEN* fb_ctx, int32_t fill )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].fill_byte = (unsigned char)fill;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorTrackID( HXCFE_FLPGEN* fb_ctx, int32_t track )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].cylinder = track;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setDiskSectorsHeadID( HXCFE_FLPGEN* fb_ctx, int32_t head )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].forced_side_id = head;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorHeadID( HXCFE_FLPGEN* fb_ctx, int32_t head )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].head = head;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorID( HXCFE_FLPGEN* fb_ctx, int32_t id )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].sector = id;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorGap3 ( HXCFE_FLPGEN* fb_ctx, int32_t Gap3 )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].gap3=Gap3;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorEncoding ( HXCFE_FLPGEN* fb_ctx, int32_t encoding )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].trackencoding = encoding;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setRPM( HXCFE_FLPGEN* fb_ctx, int32_t rpm )
|
|
{
|
|
fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].rpm = rpm;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorDataCRC ( HXCFE_FLPGEN* fb_ctx, uint32_t crc )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].use_alternate_data_crc=0xFF;
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].data_crc=crc;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorHeaderCRC ( HXCFE_FLPGEN* fb_ctx, uint32_t crc )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].use_alternate_header_crc=0xFF;
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].header_crc=crc;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setSectorDataMark ( HXCFE_FLPGEN* fb_ctx, uint32_t datamark )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].use_alternate_datamark = 0xFF;
|
|
cur_track->sc_stack[cur_track->sc_stack_pointer].alternate_datamark = datamark;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_setInterfaceMode( HXCFE_FLPGEN* fb_ctx, int32_t mode )
|
|
{
|
|
fb_track_state * cur_track;
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
cur_track->interface_mode = mode;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_popTrack ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
HXCFE_CYLINDER* currentcylinder;
|
|
fb_track_state * current_fb_track_state;
|
|
int i;
|
|
uint32_t sui_flag;
|
|
|
|
if(fb_ctx->fb_stack_pointer)
|
|
{
|
|
current_fb_track_state=&fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
if( current_fb_track_state->track_number < fb_ctx->floppydisk->floppyNumberOfTrack)
|
|
{
|
|
if(!fb_ctx->floppydisk->tracks[current_fb_track_state->track_number])
|
|
fb_ctx->floppydisk->tracks[current_fb_track_state->track_number] = allocCylinderEntry(current_fb_track_state->rpm,fb_ctx->floppydisk->floppyNumberOfSide);
|
|
|
|
currentcylinder = fb_ctx->floppydisk->tracks[current_fb_track_state->track_number];
|
|
sui_flag=0;
|
|
|
|
if(!current_fb_track_state->sectorunderindex)
|
|
sui_flag=NO_SECTOR_UNDER_INDEX;
|
|
|
|
currentcylinder->sides[current_fb_track_state->side_number] = tg_generateTrackEx((unsigned short)current_fb_track_state->numberofsector,
|
|
current_fb_track_state->sectortab,
|
|
current_fb_track_state->interleave,
|
|
current_fb_track_state->skew,
|
|
current_fb_track_state->bitrate,
|
|
current_fb_track_state->rpm,
|
|
current_fb_track_state->type,
|
|
current_fb_track_state->pregap,
|
|
current_fb_track_state->indexlen[0] | sui_flag,current_fb_track_state->indexpos[0]);
|
|
|
|
for(i=1;i<MAX_NUMBER_OF_INDEX;i++)
|
|
{
|
|
if(current_fb_track_state->indexlen[i])
|
|
{
|
|
fillindex(current_fb_track_state->indexpos[i],currentcylinder->sides[current_fb_track_state->side_number],current_fb_track_state->indexlen[i],1,0);
|
|
}
|
|
}
|
|
|
|
for(i=0;i<current_fb_track_state->numberofsector;i++)
|
|
{
|
|
hxcfe_freeSectorConfigData( 0, ¤t_fb_track_state->sectortab[i] );
|
|
}
|
|
|
|
fb_ctx->fb_stack_pointer--;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
else
|
|
{
|
|
for(i=0;i<current_fb_track_state->numberofsector;i++)
|
|
{
|
|
hxcfe_freeSectorConfigData( 0, ¤t_fb_track_state->sectortab[i] );
|
|
}
|
|
|
|
fb_ctx->fb_stack_pointer--;
|
|
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentNumberOfTrack ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->floppydisk->floppyNumberOfTrack;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentNumberOfSide ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->floppydisk->floppyNumberOfSide;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentNumberOfSector ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].numberofsector_min;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentSectorSize( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].sectors_size;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentTrackType ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].type;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentRPM ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].rpm;
|
|
}
|
|
|
|
int32_t hxcfe_getCurrentSkew ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
return fb_ctx->fb_stack[fb_ctx->fb_stack_pointer].skew;
|
|
}
|
|
|
|
int32_t hxcfe_setDiskFlags( HXCFE_FLPGEN* fb_ctx, int32_t flags )
|
|
{
|
|
fb_ctx->disk_flags = flags;
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int32_t hxcfe_generateDisk( HXCFE_FLPGEN* fb_ctx, HXCFE_FLOPPY* floppy, void * f, uint8_t * diskdata, int32_t buffersize )
|
|
{
|
|
int i,j,ret;
|
|
int numberoftracks;
|
|
int numberofsector,sectorsize;
|
|
int bufferoffset,type;
|
|
unsigned int rpm,interleave;
|
|
unsigned char * track_buffer;
|
|
unsigned char fill_byte;
|
|
int image_size;
|
|
int start_file_ofs;
|
|
int skew_per_track;
|
|
int skew_per_side;
|
|
int auto_side_id,side_id;
|
|
fb_track_state * cur_track;
|
|
FILE * filehandle;
|
|
HXCFE_SIDE* tmp_side;
|
|
int disk_bitrate;
|
|
if ( !f && !diskdata )
|
|
return HXCFE_BADPARAMETER;
|
|
|
|
filehandle = (FILE*)f;
|
|
image_size = 0;
|
|
start_file_ofs = 0;
|
|
|
|
numberoftracks = fb_ctx->floppydisk->floppyNumberOfTrack;
|
|
|
|
// Increase the track number to add the blank tracks.
|
|
if( numberoftracks > 75 && numberoftracks < 79 )
|
|
{
|
|
hxcfe_setNumberOfTrack ( fb_ctx, 79 );
|
|
}
|
|
|
|
if( numberoftracks > 78 && numberoftracks < 84 )
|
|
{
|
|
hxcfe_setNumberOfTrack ( fb_ctx, 84 );
|
|
}
|
|
|
|
if( numberoftracks > 38 && numberoftracks < 42 )
|
|
{
|
|
hxcfe_setNumberOfTrack ( fb_ctx, 42 );
|
|
}
|
|
|
|
if( filehandle )
|
|
{
|
|
start_file_ofs = ftell(filehandle);
|
|
fseek(filehandle,0,SEEK_END);
|
|
image_size = ftell(filehandle);
|
|
fseek(filehandle,start_file_ofs,SEEK_SET);
|
|
}
|
|
else
|
|
{
|
|
image_size = buffersize;
|
|
}
|
|
|
|
cur_track = &fb_ctx->fb_stack[fb_ctx->fb_stack_pointer];
|
|
|
|
sectorsize = cur_track->sectors_size;
|
|
numberofsector = cur_track->numberofsector_min;
|
|
interleave = cur_track->interleave;
|
|
rpm = cur_track->rpm;
|
|
type = cur_track->type;
|
|
skew_per_track = cur_track->skew;
|
|
skew_per_side = cur_track->side_skew;
|
|
auto_side_id = cur_track->forced_side_id;
|
|
|
|
fill_byte = cur_track->sc_stack[cur_track->sc_stack_pointer].fill_byte;
|
|
|
|
fb_ctx->floppycontext->hxc_printf(MSG_INFO_1,"Image Size:%dkB, %d tracks, %d side(s), %d sectors/track, interleave:%d,rpm:%d",(image_size-start_file_ofs)/1024,
|
|
numberoftracks,
|
|
fb_ctx->floppydisk->floppyNumberOfSide,
|
|
numberofsector,
|
|
interleave,
|
|
rpm);
|
|
|
|
track_buffer = malloc( sectorsize * numberofsector );
|
|
if( !track_buffer )
|
|
return HXCFE_INTERNALERROR;
|
|
|
|
for(i = 0 ; i < numberoftracks ; i++ )
|
|
{
|
|
for(j = 0 ; j < fb_ctx->floppydisk->floppyNumberOfSide ; j++ )
|
|
{
|
|
if( fb_ctx->disk_flags & FLPGEN_SIDES_GROUPED )
|
|
{
|
|
bufferoffset = start_file_ofs + \
|
|
( numberofsector * sectorsize * numberoftracks * j) + \
|
|
( numberofsector * sectorsize * i );
|
|
}
|
|
else
|
|
{
|
|
if( fb_ctx->floppydisk->floppyNumberOfSide == 2 )
|
|
{
|
|
bufferoffset = start_file_ofs + ( numberofsector * sectorsize * ((i<<1) + (j&1)) ) ;
|
|
}
|
|
else
|
|
{
|
|
bufferoffset = start_file_ofs + ( numberofsector * sectorsize * i );
|
|
}
|
|
}
|
|
|
|
if( filehandle )
|
|
{
|
|
fseek( filehandle, bufferoffset, SEEK_SET);
|
|
if( (bufferoffset + (numberofsector * sectorsize)) < image_size )
|
|
{
|
|
if( fread( track_buffer, numberofsector * sectorsize, 1, filehandle ) != 1 )
|
|
{
|
|
fb_ctx->floppycontext->hxc_printf(MSG_ERROR,"hxcfe_generateDisk : Error while reading the file image ! Unexpected end of file ?");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memset(track_buffer, fill_byte, sectorsize * numberofsector);
|
|
if( bufferoffset < image_size )
|
|
{
|
|
if(fread(track_buffer,image_size - bufferoffset,1,f) != 1)
|
|
{
|
|
fb_ctx->floppycontext->hxc_printf(MSG_ERROR,"hxcfe_generateDisk : Error while reading the file image ! Unexpected end of file ?");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( (bufferoffset + (numberofsector * sectorsize)) < image_size )
|
|
{
|
|
memcpy(track_buffer,&diskdata[bufferoffset],numberofsector * sectorsize);
|
|
}
|
|
else
|
|
{
|
|
memset(track_buffer, fill_byte, sectorsize * numberofsector);
|
|
if( bufferoffset < image_size )
|
|
{
|
|
memcpy(track_buffer,&diskdata[bufferoffset],image_size - bufferoffset);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!fb_ctx->floppydisk->tracks[i] || !fb_ctx->floppydisk->tracks[i]->sides[j])
|
|
{
|
|
//if(!fb_ctx->floppydisk->tracks[i]->sides[j])
|
|
{
|
|
hxcfe_pushTrack (fb_ctx,rpm,i,j,type);
|
|
|
|
hxcfe_setTrackSkew( fb_ctx, (skew_per_track*i) + (skew_per_side*j) );
|
|
|
|
if(auto_side_id < 0)
|
|
side_id = j;
|
|
else
|
|
side_id = auto_side_id;
|
|
|
|
ret = hxcfe_addSectors(fb_ctx,side_id,i,track_buffer,(sectorsize * numberofsector),numberofsector);
|
|
|
|
hxcfe_popTrack (fb_ctx);
|
|
|
|
if ( ret != HXCFE_NOERROR )
|
|
goto error;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( fb_ctx->floppydisk->floppyNumberOfSide == 2 && (fb_ctx->disk_flags & FLPGEN_FLIP_SIDES) )
|
|
{
|
|
tmp_side = fb_ctx->floppydisk->tracks[i]->sides[0];
|
|
fb_ctx->floppydisk->tracks[i]->sides[0] = fb_ctx->floppydisk->tracks[i]->sides[1];
|
|
fb_ctx->floppydisk->tracks[i]->sides[1] = tmp_side;
|
|
}
|
|
}
|
|
|
|
// Add blank tracks.
|
|
for(;i<fb_ctx->floppydisk->floppyNumberOfTrack;i++)
|
|
{
|
|
for(j = 0 ; j < fb_ctx->floppydisk->floppyNumberOfSide ; j++ )
|
|
{
|
|
hxcfe_pushTrack (fb_ctx,rpm,i,j,type);
|
|
hxcfe_popTrack (fb_ctx);
|
|
}
|
|
}
|
|
|
|
disk_bitrate = VARIABLEBITRATE;
|
|
if(fb_ctx->floppydisk->tracks[0] && fb_ctx->floppydisk->tracks[0]->sides[0])
|
|
{
|
|
disk_bitrate = fb_ctx->floppydisk->tracks[0]->sides[0]->bitrate;
|
|
}
|
|
|
|
for(i = 0 ; i < fb_ctx->floppydisk->floppyNumberOfTrack ; i++ )
|
|
{
|
|
for(j = 0 ; j < fb_ctx->floppydisk->floppyNumberOfSide ; j++ )
|
|
{
|
|
if(fb_ctx->floppydisk->tracks[i] && fb_ctx->floppydisk->tracks[i]->sides[j])
|
|
{
|
|
if( fb_ctx->floppydisk->tracks[i]->sides[j]->bitrate != disk_bitrate )
|
|
{
|
|
disk_bitrate = VARIABLEBITRATE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fb_ctx->floppydisk->floppyBitRate = disk_bitrate;
|
|
|
|
if ( floppy )
|
|
{
|
|
memcpy(floppy, fb_ctx->floppydisk , sizeof(HXCFE_FLOPPY));
|
|
floppy->floppyiftype = cur_track->interface_mode;
|
|
}
|
|
|
|
fb_ctx->floppycontext->hxc_printf(MSG_INFO_1,"track file successfully loaded and encoded!");
|
|
|
|
free( track_buffer );
|
|
|
|
free( fb_ctx->fb_stack );
|
|
free( fb_ctx );
|
|
|
|
return HXCFE_NOERROR;
|
|
|
|
error:
|
|
free( track_buffer );
|
|
|
|
free( fb_ctx->fb_stack );
|
|
free( fb_ctx );
|
|
|
|
return HXCFE_INTERNALERROR;
|
|
}
|
|
|
|
HXCFE_FLOPPY* hxcfe_getFloppy ( HXCFE_FLPGEN* fb_ctx )
|
|
{
|
|
int bitrate,trackencoding;
|
|
int i,j;
|
|
HXCFE_FLOPPY *f;
|
|
|
|
f=0;
|
|
|
|
for (j = 0; j < fb_ctx->floppydisk->floppyNumberOfTrack; j++)
|
|
{
|
|
for (i = 0; i < fb_ctx->floppydisk->floppyNumberOfSide; i++)
|
|
{
|
|
if(!fb_ctx->floppydisk->tracks[j])
|
|
{
|
|
hxcfe_pushTrack (fb_ctx,fb_ctx->fb_stack[0].rpm,j,i,fb_ctx->fb_stack[0].type);
|
|
hxcfe_popTrack (fb_ctx);
|
|
}
|
|
else
|
|
{
|
|
if(!fb_ctx->floppydisk->tracks[j]->sides[i])
|
|
{
|
|
hxcfe_pushTrack (fb_ctx,fb_ctx->fb_stack[0].rpm,j,i,fb_ctx->fb_stack[0].type);
|
|
hxcfe_popTrack (fb_ctx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(fb_ctx->floppydisk->floppyNumberOfTrack && fb_ctx->floppydisk->floppyNumberOfSide)
|
|
{
|
|
bitrate = fb_ctx->floppydisk->tracks[0]->sides[0]->bitrate;
|
|
trackencoding = fb_ctx->floppydisk->tracks[0]->sides[0]->track_encoding;
|
|
|
|
for(j=0;j<fb_ctx->floppydisk->floppyNumberOfTrack;j++)
|
|
{
|
|
for(i=0;i<fb_ctx->floppydisk->tracks[j]->number_of_side;i++)
|
|
{
|
|
if(fb_ctx->floppydisk->tracks[j]->sides[i])
|
|
{
|
|
if(bitrate != fb_ctx->floppydisk->tracks[j]->sides[i]->bitrate)
|
|
{
|
|
bitrate=-1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(i==1)
|
|
{
|
|
fb_ctx->floppydisk->tracks[j]->number_of_side--;
|
|
}
|
|
else
|
|
{
|
|
fb_ctx->floppydisk->tracks[j]->sides[i]=tg_generateTrack(0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
bitrate,
|
|
fb_ctx->floppydisk->tracks[j]->floppyRPM,
|
|
(unsigned char)trackencoding,
|
|
255,
|
|
0,
|
|
fb_ctx->fb_stack[0].indexlen[0],
|
|
fb_ctx->fb_stack[0].indexpos[0]);
|
|
|
|
for(i=1;i<MAX_NUMBER_OF_INDEX;i++)
|
|
{
|
|
if(fb_ctx->fb_stack[0].indexlen[i])
|
|
{
|
|
fillindex(fb_ctx->fb_stack[0].indexpos[0],fb_ctx->floppydisk->tracks[j]->sides[i],fb_ctx->fb_stack[0].indexlen[i],1,0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fb_ctx->floppydisk->floppyBitRate=bitrate;
|
|
|
|
f = fb_ctx->floppydisk;
|
|
free( fb_ctx->fb_stack );
|
|
free( fb_ctx );
|
|
}
|
|
|
|
return f;
|
|
}
|
|
|
|
HXCFE_FLOPPY* hxcfe_sanityCheck(HXCFE* floppycontext,HXCFE_FLOPPY * floppydisk)
|
|
{
|
|
int numberoftrack,truenumberoftrack;
|
|
int numberofside,oldnumberofside,truenumberofside;
|
|
int needanewpass;
|
|
int i;
|
|
HXCFE_SIDE ** tmpsides;
|
|
HXCFE_SIDE * currentside;
|
|
|
|
if(floppydisk)
|
|
{
|
|
// Check track parameter.
|
|
truenumberoftrack = 0;
|
|
|
|
if(floppydisk->floppyNumberOfTrack>256)
|
|
{
|
|
floppydisk->floppyNumberOfTrack=256;
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : More than 256 tracks?!? - fixed to 256. Please Check the Loader !");
|
|
}
|
|
|
|
if(!floppydisk->floppyNumberOfSide)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : 0 Side?!? - fixed to 1. Please Check the Loader !");
|
|
floppydisk->floppyNumberOfSide = 1;
|
|
}
|
|
|
|
if(floppydisk->floppyNumberOfSide>2)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : more than 2 Sides (%d) ?!? - fixed to 2. Please Check the Loader !",floppydisk->floppyNumberOfSide);
|
|
floppydisk->floppyNumberOfSide = 2;
|
|
}
|
|
|
|
if(floppydisk->floppyBitRate!=-1)
|
|
{
|
|
if(floppydisk->floppyBitRate > 1000000)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : Over 1MBit/s ?!? - fixed to 1MB/S. Please Check the Loader !");
|
|
floppydisk->floppyBitRate = 1000000;
|
|
}
|
|
|
|
if(floppydisk->floppyBitRate < 25000)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : Under 25kBit/s ?!? - fixed to 250KB/S. Please Check the Loader !");
|
|
floppydisk->floppyBitRate = 250000;
|
|
}
|
|
}
|
|
|
|
numberofside = floppydisk->floppyNumberOfSide;
|
|
|
|
if(!floppydisk->tracks)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : No track allocated ? Please Check the Loader !");
|
|
floppydisk->tracks=(HXCFE_CYLINDER**)calloc( 1, sizeof(HXCFE_CYLINDER*)*floppydisk->floppyNumberOfTrack );
|
|
if(!floppydisk->tracks)
|
|
goto alloc_error;
|
|
}
|
|
|
|
numberoftrack = floppydisk->floppyNumberOfTrack;
|
|
|
|
for( i = 0; i < numberoftrack ; i++ )
|
|
{
|
|
if( floppydisk->tracks[truenumberoftrack] )
|
|
{
|
|
truenumberoftrack++;
|
|
}
|
|
}
|
|
|
|
if( truenumberoftrack != numberoftrack)
|
|
{
|
|
truenumberoftrack=0;
|
|
while( truenumberoftrack<numberoftrack )
|
|
{
|
|
if(!floppydisk->tracks[truenumberoftrack] )
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : Track entry %d missing !",truenumberoftrack);
|
|
floppydisk->tracks[truenumberoftrack] = allocCylinderEntry(0,floppydisk->floppyNumberOfSide);
|
|
}
|
|
truenumberoftrack++;
|
|
}
|
|
}
|
|
|
|
do
|
|
{
|
|
needanewpass = 0;
|
|
numberofside = floppydisk->floppyNumberOfSide;
|
|
truenumberoftrack=0;
|
|
while( truenumberoftrack<numberoftrack )
|
|
{
|
|
truenumberofside=0;
|
|
while(truenumberofside<numberofside)
|
|
{
|
|
if(floppydisk->tracks[truenumberoftrack]->number_of_side != numberofside)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : Bad number of side (%d should be %d) at Track entry %d",floppydisk->tracks[truenumberoftrack]->number_of_side,numberofside,truenumberoftrack);
|
|
if(floppydisk->tracks[truenumberoftrack]->number_of_side < numberofside )
|
|
{
|
|
tmpsides = floppydisk->tracks[truenumberoftrack]->sides;
|
|
oldnumberofside = floppydisk->tracks[truenumberoftrack]->number_of_side;
|
|
// Realloc buffer
|
|
floppydisk->tracks[truenumberoftrack]->number_of_side = numberofside;
|
|
floppydisk->tracks[truenumberoftrack]->sides = (HXCFE_SIDE**)calloc( 1, sizeof(HXCFE_SIDE*)*numberofside);
|
|
if(!floppydisk->tracks[truenumberoftrack]->sides)
|
|
goto alloc_error;
|
|
|
|
if(tmpsides && oldnumberofside)
|
|
floppydisk->tracks[truenumberoftrack]->sides[0] = tmpsides[0];
|
|
}
|
|
else
|
|
{
|
|
if(floppydisk->tracks[truenumberoftrack]->number_of_side <= 2)
|
|
floppydisk->floppyNumberOfSide = floppydisk->tracks[truenumberoftrack]->number_of_side;
|
|
else
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : track %d - more than 2 Sides (%d) ?!? - fixed to 2. Please Check the Loader !",truenumberoftrack,floppydisk->floppyNumberOfSide);
|
|
floppydisk->tracks[truenumberoftrack]->number_of_side = 2;
|
|
}
|
|
|
|
needanewpass = 1;
|
|
}
|
|
}
|
|
truenumberofside++;
|
|
}
|
|
truenumberoftrack++;
|
|
}
|
|
}while(needanewpass);
|
|
|
|
numberoftrack = floppydisk->floppyNumberOfTrack;
|
|
numberofside = floppydisk->floppyNumberOfSide;
|
|
truenumberoftrack=0;
|
|
while( truenumberoftrack<numberoftrack )
|
|
{
|
|
truenumberofside=0;
|
|
while(truenumberofside<numberofside)
|
|
{
|
|
|
|
currentside=floppydisk->tracks[truenumberoftrack]->sides[truenumberofside];
|
|
|
|
if(!currentside)
|
|
{
|
|
currentside=(HXCFE_SIDE*)calloc( 1, sizeof(HXCFE_SIDE) );
|
|
if(!currentside)
|
|
goto alloc_error;
|
|
}
|
|
|
|
floppydisk->tracks[truenumberoftrack]->sides[truenumberofside]=currentside;
|
|
|
|
if(!currentside->databuffer)
|
|
{
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : Track %d/Side %d not allocated ?!?",truenumberoftrack,truenumberofside);
|
|
if(truenumberofside)
|
|
{
|
|
if(floppydisk->tracks[truenumberoftrack]->sides[0]->tracklen)
|
|
{
|
|
currentside->tracklen = floppydisk->tracks[truenumberoftrack]->sides[0]->tracklen;
|
|
}
|
|
else
|
|
currentside->tracklen = 12500*8;
|
|
}
|
|
else
|
|
currentside->tracklen = 12500*8;
|
|
|
|
currentside->databuffer = calloc( 1, currentside->tracklen/8 );
|
|
if(!currentside->databuffer)
|
|
goto alloc_error;
|
|
|
|
currentside->indexbuffer = calloc( 1, currentside->tracklen/8 );
|
|
if(!currentside->indexbuffer)
|
|
goto alloc_error;
|
|
|
|
if(floppydisk->floppyBitRate!=-1)
|
|
currentside->bitrate=floppydisk->floppyBitRate;
|
|
else
|
|
currentside->bitrate=250000;
|
|
|
|
fillindex(0,currentside,2500,1,0);
|
|
}
|
|
|
|
truenumberofside++;
|
|
}
|
|
truenumberoftrack++;
|
|
}
|
|
}
|
|
return floppydisk;
|
|
|
|
alloc_error:
|
|
floppycontext->hxc_printf(MSG_WARNING,"Sanity Checker : Memory allocation error !",truenumberoftrack);
|
|
return NULL;
|
|
}
|
|
|
|
fs_config fs_config_table[]=
|
|
{
|
|
{"fatst", "",FS_720KB_ATARI_FAT12,0},
|
|
{"fatst902", "",FS_902KB_ATARI_FAT12,0},
|
|
{"fatst360", "",FS_360KB_ATARI_FAT12,0},
|
|
{"amigados", "3\"5 880KB DSDD AmigaDOS",FS_880KB_AMIGADOS,1},
|
|
|
|
{"amigados_hd", "3\"5 1760KB DSHD AmigaDOS",FS_1760KB_AMIGADOS,2},
|
|
|
|
{"fat160a", "5\"25 & 8\" 160KB SSDD 300RPM FAT12",FS_5P25_300RPM_160KB_MSDOS_FAT12,0},
|
|
{"fat160b", "5\"25 & 8\" 160KB SSDD 360RPM FAT12",FS_5P25_360RPM_160KB_MSDOS_FAT12,0},
|
|
|
|
{"fat180a", "5\"25 180KB SSDD 300RPM FAT12",FS_5P25_300RPM_180KB_MSDOS_FAT12,0},
|
|
{"fat180b", "5\"25 180KB SSDD 360RPM FAT12",FS_5P25_360RPM_180KB_MSDOS_FAT12,0},
|
|
|
|
{"fat320ssa", "5\"25 320KB SSDD 300RPM FAT12",FS_5P25_SS_300RPM_320KB_MSDOS_FAT12,0},
|
|
{"fat320ssb", "5\"25 320KB SSDD 360RPM FAT12",FS_5P25_SS_360RPM_320KB_MSDOS_FAT12,0},
|
|
|
|
{"fat320dsa", "5\"25 320KB DSDD 300RPM FAT12",FS_5P25_DS_300RPM_320KB_MSDOS_FAT12,0},
|
|
{"fat320dsb", "5\"25 320KB DSDD 360RPM FAT12",FS_5P25_DS_360RPM_320KB_MSDOS_FAT12,0},
|
|
|
|
{"fat360a", "5\"25 & 8\" 360KB DSDD 300RPM FAT12",FS_5P25_DS_300RPM_360KB_MSDOS_FAT12,0},
|
|
{"fat360b", "5\"25 & 8\" 360KB DSDD 360RPM FAT12",FS_5P25_DS_360RPM_360KB_MSDOS_FAT12,0},
|
|
|
|
{"fat640", "3\"5 640KB DSDD FAT12",FS_3P5_DS_300RPM_640KB_MSDOS_FAT12,0},
|
|
|
|
{"fat720", "3\"5 720KB DSDD FAT12",FS_720KB_MSDOS_FAT12,0},
|
|
{"fat738", "3\"5 738KB DSDD FAT12",FS_738KB_MSDOS_FAT12,0},
|
|
{"fat800", "3\"5 800KB DSDD FAT12",FS_800KB_MSDOS_FAT12,0},
|
|
{"fat820", "3\"5 820KB DSDD FAT12",FS_820KB_MSDOS_FAT12,0},
|
|
|
|
{"fat1200", "5\"25 1.2MB DSHD FAT12",FS_5P25_300RPM_1200KB_MSDOS_FAT12,0},
|
|
{"fat1230", "5\"25 1.23MB DSHD FAT12",FS_5P25_300RPM_1230KB_MSDOS_FAT12,0},
|
|
|
|
{"fat1440", "3\"5 1.44MB DSHD FAT12",FS_1_44MB_MSDOS_FAT12,0},
|
|
{"fat1476", "3\"5 1.478MB DSHD FAT12",FS_1_476MB_MSDOS_FAT12,0},
|
|
|
|
{"fat1600", "3\"5 1.6MB DSHD FAT12",FS_1_600MB_MSDOS_FAT12,0},
|
|
{"fat1640", "3\"5 1.64MB DSHD FAT12",FS_1_640MB_MSDOS_FAT12,0},
|
|
{"fat1680", "3\"5 1.68MB DSHD FAT12",FS_1_68MB_MSDOS_FAT12,0},
|
|
|
|
{"fat1722", "3\"5 1.722MB DSHD FAT12",FS_1_722MB_MSDOS_FAT12,0},
|
|
{"fat1743", "3\"5 1.743MB DSHD FAT12",FS_1_743MB_MSDOS_FAT12,0},
|
|
{"fat1764", "3\"5 1.764MB DSHD FAT12",FS_1_764MB_MSDOS_FAT12,0},
|
|
{"fat1785", "3\"5 1.785MB DSHD FAT12",FS_1_785MB_MSDOS_FAT12,0},
|
|
|
|
{"fat2540", "3\"5 2.50MB DSDD FAT12",FS_2_50MB_MSDOS_FAT12,0},
|
|
|
|
{"fat2880", "3\"5 2.88MB DSED FAT12",FS_2_88MB_MSDOS_FAT12,0},
|
|
{"fat3381", "3\"5 3.38MB DSHD FAT12",FS_3_38MB_MSDOS_FAT12,0},
|
|
{"fatbigst", "3\"5 3.42MB DSDD Atari FAT12",FS_3_42MB_ATARI_FAT12,0},
|
|
|
|
{"fat5355", "3\"5 5.35MB DSHD FAT12",FS_5_35MB_MSDOS_FAT12,0},
|
|
{"fat5355b", "3\"5 5.35MB DSHD FAT12",FS_5_35MB_B_MSDOS_FAT12,0},
|
|
|
|
{"fat6789", "3\"5 6.78MB DSHD FAT12",FS_6_78MB_MSDOS_FAT12,0},
|
|
{"fatbig", "",FS_16MB_MSDOS_FAT12,0},
|
|
{"fat4572", "3\"5 4.50MB DSHD FAT12",FS_4_50MB_MSDOS_FAT12,0},
|
|
{0,0,0,0}
|
|
};
|
|
|
|
|
|
HXCFE_FLOPPY * hxcfe_generateFloppy( HXCFE* floppycontext, char* path, int32_t fsID, int32_t * err_ret )
|
|
{
|
|
int ret;
|
|
HXCFE_FLOPPY * newfloppy;
|
|
HXCFE_IMGLDR * imgldr_ctx;
|
|
plugins_ptr func_ptr;
|
|
int moduleID;
|
|
int i;
|
|
image_plugin* plugin_ptr;
|
|
|
|
floppycontext->hxc_printf(MSG_INFO_0,"Create file system (source path : %s) ...",path);
|
|
|
|
plugin_ptr = (image_plugin*)floppycontext->image_handlers;
|
|
|
|
newfloppy = 0;
|
|
|
|
imgldr_ctx = hxcfe_imgInitLoader(floppycontext);
|
|
if(imgldr_ctx)
|
|
{
|
|
if( fsID == FS_880KB_AMIGADOS || fsID == FS_1760KB_AMIGADOS )
|
|
moduleID = hxcfe_imgGetLoaderID (imgldr_ctx,PLUGIN_AMIGA_FS);
|
|
else
|
|
moduleID = hxcfe_imgGetLoaderID (imgldr_ctx,PLUGIN_FAT12FLOPPY);
|
|
|
|
i=0;
|
|
while(fs_config_table[i].name && (fs_config_table[i].fsID != fsID))
|
|
{
|
|
i++;
|
|
}
|
|
|
|
if(hxcfe_checkLoaderID(imgldr_ctx,moduleID)==HXCFE_NOERROR && fs_config_table[i].name)
|
|
{
|
|
ret = plugin_ptr[moduleID].infos_handler(imgldr_ctx,GETFUNCPTR,&func_ptr);
|
|
if(ret==HXCFE_NOERROR)
|
|
{
|
|
newfloppy = calloc( 1, sizeof(HXCFE_FLOPPY) );
|
|
if(newfloppy)
|
|
{
|
|
floppycontext->hxc_printf(MSG_INFO_0,"file loader found!");
|
|
|
|
ret=func_ptr.libLoad_DiskFile(imgldr_ctx,newfloppy,path,fs_config_table[i].name);
|
|
if(ret!=HXCFE_NOERROR)
|
|
{
|
|
free( newfloppy );
|
|
newfloppy = NULL;
|
|
}
|
|
|
|
if(err_ret)
|
|
*err_ret=ret;
|
|
|
|
hxcfe_imgDeInitLoader(imgldr_ctx);
|
|
}
|
|
|
|
return newfloppy;
|
|
}
|
|
}
|
|
|
|
floppycontext->hxc_printf(MSG_ERROR,"Bad plugin ID : 0x%x",moduleID);
|
|
|
|
ret=HXCFE_BADPARAMETER;
|
|
|
|
if(err_ret)
|
|
*err_ret=ret;
|
|
|
|
hxcfe_imgDeInitLoader(imgldr_ctx);
|
|
}
|
|
return newfloppy;
|
|
}
|
|
|
|
int32_t hxcfe_getTrackBitrate( HXCFE* floppycontext, HXCFE_FLOPPY * fp, int32_t track, int32_t side )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->tracks[track]->sides[side]->bitrate;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getTrackEncoding( HXCFE* floppycontext, HXCFE_FLOPPY * fp, int32_t track, int32_t side )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->tracks[track]->sides[side]->track_encoding;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getTrackLength( HXCFE* floppycontext, HXCFE_FLOPPY * fp, int32_t track, int32_t side )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->tracks[track]->sides[side]->tracklen;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getTrackRPM( HXCFE* floppycontext, HXCFE_FLOPPY * fp, int32_t track )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->tracks[track]->floppyRPM;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getTrackNumberOfSide( HXCFE* floppycontext, HXCFE_FLOPPY * fp, int32_t track )
|
|
{
|
|
if(fp)
|
|
{
|
|
return fp->tracks[track]->number_of_side;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int track_hash( HXCFE* floppycontext, HXCFE_FLOPPY * floppydisk, int track, int side, int type, uint32_t * crc32 )
|
|
{
|
|
HXCFE_SECTORACCESS* ss;
|
|
HXCFE_SECTCFG* sc;
|
|
|
|
ss = hxcfe_initSectorAccess(floppycontext,floppydisk);
|
|
if( ss )
|
|
{
|
|
do
|
|
{
|
|
sc = hxcfe_getNextSector(ss,track,side,type);
|
|
if( sc )
|
|
{
|
|
///////////////////////////////////////
|
|
// Data Block
|
|
///////////////////////////////////////
|
|
if( sc->startdataindex == sc->startsectorindex )
|
|
{
|
|
// Header less sector
|
|
}
|
|
else
|
|
{
|
|
if( sc->use_alternate_data_crc )
|
|
{
|
|
// CRC error
|
|
}
|
|
else
|
|
{
|
|
if( crc32 )
|
|
{
|
|
if(sc->input_data && !sc->use_alternate_data_crc)
|
|
{
|
|
*crc32 = std_crc32(*crc32, sc->input_data, sc->sectorsize);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hxcfe_freeSectorConfig( ss, sc );
|
|
|
|
}
|
|
}while(sc);
|
|
|
|
hxcfe_deinitSectorAccess( ss );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t hxcfe_getHash( HXCFE* floppycontext, HXCFE_FLOPPY * fp, int32_t track, int32_t side, int32_t sector, uint32_t formats, int hashtype, uint32_t flags, void * hashbuffer, int hashmaxsize )
|
|
{
|
|
if(fp)
|
|
{
|
|
int i, maxtrack,maxside;
|
|
uint32_t crc32;
|
|
|
|
crc32 = 0x00000000;
|
|
|
|
if(track < 0)
|
|
{
|
|
track = 0;
|
|
maxtrack = fp->floppyNumberOfTrack;
|
|
}
|
|
else
|
|
{
|
|
maxtrack = track + 1;
|
|
}
|
|
|
|
if(side < 0)
|
|
{
|
|
side = 0;
|
|
maxside = fp->floppyNumberOfSide;
|
|
}
|
|
else
|
|
{
|
|
maxside = side + 1;
|
|
}
|
|
|
|
for(track=0; track < maxtrack; track++)
|
|
{
|
|
for(side=0; side < maxside; side++)
|
|
{
|
|
//////////////////////////////////////////
|
|
// Sector drawing
|
|
for(i=0;i<32;i++)
|
|
{
|
|
if( formats & (0x00000001<<i) )
|
|
{
|
|
track_hash( floppycontext, fp, track, side, i, &crc32 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
memcpy(hashbuffer,&crc32,sizeof(uint32_t));
|
|
}
|
|
return HXCFE_NOERROR;
|
|
}
|