mirror of
https://github.com/jfdelnero/HxCFloppyEmulator.git
synced 2026-07-28 04:06:36 +00:00
1416 lines
32 KiB
C
1416 lines
32 KiB
C
/*
|
|
//
|
|
// Copyright (C) 2006-2024 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 : xml_disk.c
|
|
// Contains: raw disk loader/creator
|
|
//
|
|
// 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 <expat.h>
|
|
|
|
#include "internal_libhxcfe.h"
|
|
#include "libhxcfe.h"
|
|
#include "floppy_loader.h"
|
|
#include "floppy_utils.h"
|
|
#include "libhxcadaptor.h"
|
|
|
|
#include "xml_disk.h"
|
|
#include "./DiskLayouts/LayoutsIndex.h"
|
|
#include "./packer/pack.h"
|
|
|
|
#define XML_STRING_MAXSIZE 512
|
|
|
|
typedef struct parse_stack_
|
|
{
|
|
int32_t state;
|
|
int32_t track_type;
|
|
int32_t cur_track;
|
|
}parse_stack;
|
|
|
|
typedef struct track_state_
|
|
{
|
|
int32_t base_adress;
|
|
int32_t track_size;
|
|
int32_t set;
|
|
}track_state;
|
|
|
|
#define MAX_TRACKS_NB 256
|
|
|
|
typedef struct app_data
|
|
{
|
|
HXCFE* floppycontext;
|
|
|
|
int32_t current_state;
|
|
void * p;
|
|
|
|
int32_t stack_ptr;
|
|
|
|
int32_t layout_id;
|
|
char * xmlfile_path[512];
|
|
|
|
parse_stack statestack[32];
|
|
|
|
HXCFE_FLPGEN * fb;
|
|
HXCFE_FLOPPY* floppy;
|
|
|
|
track_state ts[MAX_TRACKS_NB*2];
|
|
|
|
int32_t xmlcheck;
|
|
|
|
char name[XML_STRING_MAXSIZE];
|
|
char description[XML_STRING_MAXSIZE];
|
|
char file_extensions[XML_STRING_MAXSIZE];
|
|
|
|
uint8_t * image_data;
|
|
|
|
uint8_t * sector_data;
|
|
int32_t sector_data_offset;
|
|
|
|
int32_t buffer_size;
|
|
|
|
int32_t skew_per_track;
|
|
int32_t skew_per_side;
|
|
|
|
int32_t interface_mode;
|
|
int32_t double_step;
|
|
|
|
int32_t write_protect;
|
|
|
|
int32_t fill_value;
|
|
|
|
int32_t min_nb_of_tracks;
|
|
int32_t max_nb_of_tracks;
|
|
int32_t nb_of_tracks;
|
|
|
|
int32_t min_nb_of_sides;
|
|
int32_t max_nb_of_sides;
|
|
int32_t nb_of_sides;
|
|
|
|
int32_t file_size;
|
|
|
|
int32_t nb_sectors_per_track;
|
|
int32_t sector_size;
|
|
|
|
int32_t index_length;
|
|
int32_t cur_index_number;
|
|
|
|
} AppData;
|
|
|
|
char * get_ext(int index,char * bufin,char * bufferout)
|
|
{
|
|
int i,j;
|
|
|
|
j = 0;
|
|
i = 0;
|
|
while( (i < index) && bufin[j])
|
|
{
|
|
while( ( bufin[j] != ',' ) && bufin[j] )
|
|
{
|
|
j++;
|
|
}
|
|
|
|
i++;
|
|
if(bufin[j])
|
|
j++;
|
|
}
|
|
|
|
if(bufin[j])
|
|
{
|
|
if(bufin[j] == ',')
|
|
j++;
|
|
|
|
i = 0;
|
|
bufferout[i] = 0;
|
|
do
|
|
{
|
|
bufferout[i] = bufin[j];
|
|
i++;
|
|
j++;
|
|
}while(bufin[j] != ',' && bufin[j]);
|
|
bufferout[i] = 0;
|
|
|
|
return bufferout;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int is_ext_matching(char * filename,char * extlist)
|
|
{
|
|
int i;
|
|
char temp_ext[8];
|
|
char * ptr;
|
|
|
|
i = 0;
|
|
do{
|
|
ptr = get_ext(i,extlist,(char*)&temp_ext);
|
|
|
|
if(ptr)
|
|
{
|
|
if( hxc_checkfileext(filename,ptr,SYS_PATH_TYPE) )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}while(ptr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int generateDisk(AppData *ad,unsigned char * diskdata,int buffersize)
|
|
{
|
|
int i,j,ret;
|
|
int numberofsector,numberoftrack,numberofside,sectorsize;
|
|
int type;
|
|
int statetracknb;
|
|
unsigned int rpm;
|
|
int offset;
|
|
unsigned char * partialbuf;
|
|
|
|
offset = 0;
|
|
sectorsize = hxcfe_getCurrentSectorSize(ad->fb);
|
|
numberofsector = hxcfe_getCurrentNumberOfSector(ad->fb);
|
|
numberoftrack = hxcfe_getCurrentNumberOfTrack(ad->fb);
|
|
numberofside = hxcfe_getCurrentNumberOfSide(ad->fb);
|
|
rpm = hxcfe_getCurrentRPM(ad->fb);
|
|
type = hxcfe_getCurrentTrackType(ad->fb);
|
|
|
|
for(i = 0 ; i < numberoftrack ; i++ )
|
|
{
|
|
for(j = 0 ; j < numberofside ; j++ )
|
|
{
|
|
statetracknb = (i<<1) | (j&1);
|
|
|
|
if(!ad->ts[statetracknb].set)
|
|
{
|
|
|
|
hxcfe_pushTrack (ad->fb,rpm,i,j,type);
|
|
|
|
hxcfe_setTrackSkew(ad->fb, (hxcfe_getCurrentSkew(ad->fb) + ( ad->skew_per_track * i ) + ( j * ad->skew_per_side ))%numberofsector );
|
|
|
|
if( ( offset >= buffersize) || !diskdata )
|
|
{
|
|
ret = hxcfe_addSectors(ad->fb,j,i,0,0,numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"generateDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
}
|
|
else
|
|
{
|
|
|
|
if(buffersize - offset >= (sectorsize * numberofsector) )
|
|
{
|
|
ret = hxcfe_addSectors(ad->fb,j,i,&diskdata[offset],(sectorsize * numberofsector),numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"generateDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
}
|
|
else
|
|
{
|
|
partialbuf = malloc(sectorsize * numberofsector);
|
|
if(partialbuf)
|
|
{
|
|
memset(partialbuf,ad->fill_value,sectorsize * numberofsector);
|
|
memcpy(partialbuf,&diskdata[offset],buffersize - offset);
|
|
|
|
ret = hxcfe_addSectors(ad->fb,j,i,partialbuf,(sectorsize * numberofsector),numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"generateDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
free(partialbuf);
|
|
}
|
|
else
|
|
{
|
|
ret = hxcfe_addSectors(ad->fb,j,i,0,0,numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"generateDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
offset = offset + (sectorsize * numberofsector);
|
|
hxcfe_popTrack (ad->fb);
|
|
}
|
|
else
|
|
{
|
|
offset = ad->ts[statetracknb].base_adress + ad->ts[statetracknb].track_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int dumpDisk(AppData *ad,unsigned char * diskdata,int buffersize,HXCFE_FLOPPY * fp)
|
|
{
|
|
int i,j,ret;
|
|
int numberofsector,numberoftrack,numberofside,sectorsize;
|
|
int type;
|
|
int statetracknb;
|
|
unsigned int rpm;
|
|
int offset;
|
|
unsigned char * partialbuf;
|
|
|
|
offset = 0;
|
|
sectorsize = hxcfe_getCurrentSectorSize(ad->fb);
|
|
numberofsector = hxcfe_getCurrentNumberOfSector(ad->fb);
|
|
numberoftrack = hxcfe_getCurrentNumberOfTrack(ad->fb);
|
|
numberofside = hxcfe_getCurrentNumberOfSide(ad->fb);
|
|
rpm = hxcfe_getCurrentRPM(ad->fb);
|
|
type = hxcfe_getCurrentTrackType(ad->fb);
|
|
|
|
for(i = 0 ; i < numberoftrack ; i++ )
|
|
{
|
|
for(j = 0 ; j < numberofside ; j++ )
|
|
{
|
|
statetracknb = (i<<1) | (j&1);
|
|
|
|
if(!ad->ts[statetracknb].set)
|
|
{
|
|
|
|
hxcfe_pushTrack (ad->fb,rpm,i,j,type);
|
|
|
|
hxcfe_setTrackSkew(ad->fb, (hxcfe_getCurrentSkew(ad->fb) + ( ad->skew_per_track * i ) + ( j * ad->skew_per_side ))%numberofsector );
|
|
|
|
|
|
if( ( offset >= buffersize) || !diskdata )
|
|
{
|
|
ret = hxcfe_addSectors(ad->fb,j,i,0,0,numberofsector);
|
|
}
|
|
else
|
|
{
|
|
|
|
if(buffersize - offset >= (sectorsize * numberofsector) )
|
|
{
|
|
ret = hxcfe_addSectors(ad->fb,j,i,&diskdata[offset],(sectorsize * numberofsector),numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"dumpDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
}
|
|
else
|
|
{
|
|
partialbuf = malloc(sectorsize * numberofsector);
|
|
if(partialbuf)
|
|
{
|
|
memset(partialbuf,ad->fill_value,sectorsize * numberofsector);
|
|
memcpy(partialbuf,&diskdata[offset],buffersize - offset);
|
|
|
|
ret = hxcfe_addSectors(ad->fb,j,i,partialbuf,(sectorsize * numberofsector),numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"dumpDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
|
|
free(partialbuf);
|
|
}
|
|
else
|
|
{
|
|
ret = hxcfe_addSectors(ad->fb,j,i,0,0,numberofsector);
|
|
if(ret != HXCFE_NOERROR)
|
|
ad->floppycontext->hxc_printf(MSG_ERROR,"dumpDisk : hxcfe_addSectors failed -> %d !",ret);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
offset = offset + (sectorsize * numberofsector);
|
|
hxcfe_popTrack (ad->fb);
|
|
}
|
|
else
|
|
{
|
|
offset = ad->ts[statetracknb].base_adress + ad->ts[statetracknb].track_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
int getnewstate(char * keyword, int currentstate)
|
|
{
|
|
int i;
|
|
|
|
i=0;
|
|
|
|
while(keyword_list[i].keyword)
|
|
{
|
|
if( !strcmp( keyword_list[i].keyword ,keyword) && ( currentstate == keyword_list[i].prev_state) )
|
|
{
|
|
return keyword_list[i].state;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int getstate(char * keyword, int currentstate)
|
|
{
|
|
int i;
|
|
|
|
i=0;
|
|
|
|
while(keyword_list[i].keyword)
|
|
{
|
|
if( !strcmp( keyword_list[i].keyword ,keyword) && ( currentstate == keyword_list[i].state) )
|
|
{
|
|
return keyword_list[i].state;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
uint32_t ahextoi(char * str)
|
|
{
|
|
uint32_t hexval;
|
|
int i;
|
|
unsigned char c;
|
|
|
|
hexval = 0;
|
|
i = 0;
|
|
|
|
while(str[i])
|
|
{
|
|
c = str[i];
|
|
|
|
if( ( c>='0' && c<='9' ) || ( c>='a' && c<='f' ) || ( c>='A' && c<='F' ) )
|
|
{
|
|
hexval = hexval << 4;
|
|
|
|
if( c>='0' && c<='9' )
|
|
{
|
|
hexval = hexval | (c - '0');
|
|
}
|
|
else
|
|
{
|
|
if(( c>='a' && c<='f' ))
|
|
{
|
|
hexval = hexval | ( (c - 'a') + 10);
|
|
}
|
|
else
|
|
{
|
|
hexval = hexval | ( (c - 'A') + 10);
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hexval = 0;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return hexval;
|
|
}
|
|
|
|
static void XMLCALL charhandler(void *data, const char *s, int len)
|
|
{
|
|
AppData *ad = (AppData *) data;
|
|
char * buffer;
|
|
unsigned int datamark;
|
|
unsigned int crc;
|
|
int track,sectorsize,i;
|
|
int tmp_base_adress;
|
|
|
|
buffer = malloc(len + 1);
|
|
if(!buffer) return;
|
|
|
|
memset(buffer,0,len + 1);
|
|
memcpy(buffer,s,len);
|
|
|
|
switch(ad->current_state)
|
|
{
|
|
case DISK_LAYOUT_NAME:
|
|
strncpy((char*)&ad->name,(char*)buffer,XML_STRING_MAXSIZE - 1);
|
|
ad->name[XML_STRING_MAXSIZE - 1] = 0;
|
|
break;
|
|
case DISK_LAYOUT_DESCRIPTION:
|
|
strncpy((char*)&ad->description,(char*)buffer,XML_STRING_MAXSIZE - 1);
|
|
ad->description[XML_STRING_MAXSIZE - 1] = 0;
|
|
break;
|
|
case FILEEXT:
|
|
strncpy((char*)&ad->file_extensions,(char*)buffer,XML_STRING_MAXSIZE - 1);
|
|
ad->file_extensions[XML_STRING_MAXSIZE - 1] = 0;
|
|
break;
|
|
case INTERFACE_MODE:
|
|
ad->interface_mode = hxcfe_getFloppyInterfaceModeID(ad->floppycontext,(char*)buffer);
|
|
break;
|
|
case DOUBLE_STEP:
|
|
if(!strcmp(buffer,"on"))
|
|
ad->double_step = 1;
|
|
|
|
if(!strcmp(buffer,"off"))
|
|
ad->double_step = 0;
|
|
break;
|
|
case FILESIZE:
|
|
ad->file_size = atoi(buffer);
|
|
break;
|
|
case WRITE_PROTECT:
|
|
ad->write_protect = atoi(buffer);
|
|
break;
|
|
/* case TRACKSIZE:
|
|
ad->track_size = atoi(buffer);
|
|
break;*/
|
|
case MINNUMBEROFTRACKS:
|
|
ad->min_nb_of_tracks = atoi(buffer);
|
|
break;
|
|
case MAXNUMBEROFTRACKS:
|
|
ad->max_nb_of_tracks = atoi(buffer);
|
|
break;
|
|
|
|
case NUMBEROFTRACK:
|
|
ad->nb_of_tracks = atoi(buffer);
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setNumberOfTrack (ad->fb,(unsigned short)ad->nb_of_tracks);
|
|
break;
|
|
case NUMBEROFSIDE:
|
|
ad->nb_of_sides = (unsigned short)atoi(buffer);
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setNumberOfSide (ad->fb,(unsigned char)ad->nb_of_sides);
|
|
break;
|
|
case NUMBEROFSECTOR:
|
|
ad->nb_sectors_per_track = (unsigned short)atoi(buffer);
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setNumberOfSector (ad->fb,(unsigned short)ad->nb_sectors_per_track);
|
|
break;
|
|
case SECTORSIZE:
|
|
ad->sector_size = (unsigned short)atoi(buffer);
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setSectorSize(ad->fb,ad->sector_size);
|
|
break;
|
|
case INTERLEAVE_TRACK:
|
|
case INTERLEAVE:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setTrackInterleave(ad->fb,atoi(buffer));
|
|
break;
|
|
case SKEW_TRACK:
|
|
case SKEW:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setTrackSkew(ad->fb,atoi(buffer));
|
|
break;
|
|
case SKEW_PER_TRACK:
|
|
ad->skew_per_track = atoi(buffer);
|
|
break;
|
|
case SKEW_PER_SIDE:
|
|
ad->skew_per_side = atoi(buffer);
|
|
break;
|
|
case FORMATVALUE:
|
|
case DATAFILL_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
hxcfe_setSectorFill (ad->fb,(unsigned char)ahextoi(buffer));
|
|
}
|
|
|
|
ad->fill_value = ahextoi(buffer);
|
|
break;
|
|
case FORMAT_TRACK:
|
|
case FORMAT:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = IBMFORMAT_DD;
|
|
|
|
if(!strcmp(buffer,"ISO_MFM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = ISOFORMAT_DD;
|
|
}
|
|
if(!strcmp(buffer,"IBM_MFM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = IBMFORMAT_DD;
|
|
}
|
|
if(!strcmp(buffer,"ISO_FM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = ISOFORMAT_SD;
|
|
}
|
|
if(!strcmp(buffer,"IBM_FM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = IBMFORMAT_SD;
|
|
}
|
|
if(!strcmp(buffer,"DECRX02_M2FM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = DECRX02_SDDD;
|
|
}
|
|
if(!strcmp(buffer,"UKNC_MFM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = UKNCFORMAT_DD;
|
|
}
|
|
if(!strcmp(buffer,"AMIGA_MFM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = AMIGAFORMAT_DD;
|
|
}
|
|
if(!strcmp(buffer,"AED6200P_MFM"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = AED6200P_DD;
|
|
}
|
|
if(!strcmp(buffer,"VICTOR9K_GCR"))
|
|
{
|
|
ad->statestack[ad->stack_ptr].track_type = VICTOR9K_GCR;
|
|
}
|
|
|
|
hxcfe_setTrackType(ad->fb,ad->statestack[ad->stack_ptr].track_type);
|
|
}
|
|
break;
|
|
case TRACK_PREGAP:
|
|
case PREGAP:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setTrackPreGap (ad->fb,(unsigned short)atoi(buffer));
|
|
break;
|
|
case TRACK_PREGAP_US:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setTrackPreGap (ad->fb,atoi(buffer) | 0x40000000);
|
|
break;
|
|
case TRACK_GAP3:
|
|
case GAP3:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setSectorGap3 (ad->fb,(unsigned char)atoi(buffer));
|
|
break;
|
|
case RPM:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setRPM (ad->fb,(unsigned short)atoi(buffer));
|
|
break;
|
|
case TRACK_LENGTH:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setRPM (ad->fb,(atoi(buffer)/10) | 0x40000000);
|
|
break;
|
|
case SECTORIDSTART:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setStartSectorID(ad->fb,(unsigned char)atoi(buffer));
|
|
break;
|
|
case TRACKID_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setSectorTrackID(ad->fb,(unsigned char)atoi(buffer));
|
|
break;
|
|
case SIDEID_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setSectorHeadID(ad->fb,(unsigned char)atoi(buffer));
|
|
break;
|
|
case SECTORID_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setSectorID(ad->fb,(unsigned char)atoi(buffer));
|
|
break;
|
|
|
|
case BITRATE:
|
|
if(!ad->xmlcheck)
|
|
hxcfe_setTrackBitrate(ad->fb,atoi(buffer));
|
|
break;
|
|
case DATAOFFSET:
|
|
track = ad->statestack[ad->stack_ptr].cur_track;
|
|
ad->ts[track].base_adress = ahextoi(buffer);
|
|
break;
|
|
case DATAOFFSETSECTOR:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
track = ad->statestack[ad->stack_ptr].cur_track;
|
|
tmp_base_adress = ahextoi(buffer);
|
|
|
|
sectorsize = hxcfe_getCurrentSectorSize(ad->fb);
|
|
|
|
if(tmp_base_adress + sectorsize < ad->buffer_size)
|
|
{
|
|
hxcfe_setSectorData(ad->fb,&ad->image_data[tmp_base_adress],sectorsize);
|
|
}
|
|
}
|
|
break;
|
|
case DATAMARK_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
sscanf(buffer,"0x%X",&datamark);
|
|
hxcfe_setSectorDataMark (ad->fb,(unsigned char)datamark);
|
|
}
|
|
break;
|
|
case DATACRC_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
sscanf(buffer,"0x%X",&crc);
|
|
hxcfe_setSectorDataCRC (ad->fb,(unsigned short)crc);
|
|
}
|
|
break;
|
|
case HEADERCRC_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
sscanf(buffer,"0x%X",&crc);
|
|
hxcfe_setSectorHeaderCRC (ad->fb,(unsigned short)crc);
|
|
}
|
|
break;
|
|
case SECTORDATA_SECTOR:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
sectorsize = hxcfe_getCurrentSectorSize(ad->fb);
|
|
|
|
if(!ad->sector_data)
|
|
{
|
|
ad->sector_data = malloc(sectorsize);
|
|
if(ad->sector_data)
|
|
{
|
|
memset(ad->sector_data,0x00,sectorsize);
|
|
}
|
|
ad->sector_data_offset = 0;
|
|
}
|
|
|
|
if(ad->sector_data)
|
|
{
|
|
for(i=0;i<len/2;i++)
|
|
{
|
|
if(buffer[i*2]>='A')
|
|
ad->sector_data[ad->sector_data_offset] = (uint8_t)(((buffer[i*2] - 'A') + 10 ) << 4);
|
|
else
|
|
ad->sector_data[ad->sector_data_offset] = (uint8_t)(((buffer[i*2] - '0') ) << 4);
|
|
|
|
if(buffer[(i*2)+1]>='A')
|
|
ad->sector_data[ad->sector_data_offset] |= (uint8_t)(((buffer[(i*2)+1] - 'A') + 10) & 0xF);
|
|
else
|
|
ad->sector_data[ad->sector_data_offset] |= (uint8_t)(((buffer[(i*2)+1] - '0')) & 0xF);
|
|
|
|
ad->sector_data_offset++;
|
|
if( ad->sector_data_offset == sectorsize )
|
|
ad->sector_data_offset = sectorsize - 1;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SET_INDEX_LENGTH:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
ad->index_length = atoi(buffer);
|
|
hxcfe_setIndexLength(ad->fb,ad->cur_index_number,ad->index_length);
|
|
}
|
|
break;
|
|
|
|
case SET_INDEX_POSITION:
|
|
if(!ad->xmlcheck)
|
|
{
|
|
hxcfe_setIndexLength(ad->fb,ad->cur_index_number,ad->index_length);
|
|
hxcfe_setIndexPosition(ad->fb,ad->cur_index_number,atoi(buffer),1);
|
|
}
|
|
|
|
ad->cur_index_number++;
|
|
break;
|
|
}
|
|
|
|
free(buffer);
|
|
}
|
|
|
|
static void XMLCALL start(void *data, const char *el, const char **attr)
|
|
{
|
|
int i;
|
|
int newstate;
|
|
int track,side,sector,sectorsize;
|
|
AppData *ad = (AppData *) data;
|
|
|
|
sector = 0xFF;
|
|
sectorsize = 128;
|
|
|
|
newstate = getnewstate((char*)el, ad->current_state);
|
|
if ( newstate >= 0 )
|
|
{
|
|
ad->stack_ptr++;
|
|
memcpy(&ad->statestack[ad->stack_ptr], &ad->statestack[ad->stack_ptr-1],sizeof(parse_stack));
|
|
ad->statestack[ad->stack_ptr].state = newstate;
|
|
ad->current_state = newstate;
|
|
|
|
switch(ad->current_state)
|
|
{
|
|
case LAYOUT:
|
|
if(!ad->xmlcheck)
|
|
ad->fb = hxcfe_initFloppy(ad->floppycontext,80,2);
|
|
break;
|
|
case TRACK:
|
|
i=0;
|
|
side=0;
|
|
track=0;
|
|
|
|
while(attr[i] && strcmp("track_number",attr[i]) )
|
|
{
|
|
i++;
|
|
}
|
|
if(attr[i+1])
|
|
{
|
|
track = atoi(attr[i+1]);
|
|
}
|
|
|
|
i=0;
|
|
while(attr[i] && strcmp("side_number",attr[i]) )
|
|
{
|
|
i++;
|
|
}
|
|
if(attr[i+1])
|
|
{
|
|
side = atoi(attr[i+1]);
|
|
}
|
|
|
|
ad->statestack[ad->stack_ptr].cur_track = (track<<1) | (side&1);
|
|
ad->ts[(track<<1) | (side&1)].set=1;
|
|
|
|
if(!ad->xmlcheck)
|
|
hxcfe_pushTrackPFS (ad->fb,track,side);
|
|
break;
|
|
|
|
case SECTOR:
|
|
i=0;
|
|
while(attr[i] && strcmp("sector_id",attr[i]) )
|
|
{
|
|
i++;
|
|
}
|
|
if(attr[i+1])
|
|
{
|
|
sector = atoi(attr[i+1]);
|
|
}
|
|
|
|
i=0;
|
|
while(attr[i] && strcmp("sector_size",attr[i]) )
|
|
{
|
|
i++;
|
|
}
|
|
if(attr[i+1])
|
|
{
|
|
sectorsize = atoi(attr[i+1]);
|
|
}
|
|
|
|
track = ad->statestack[ad->stack_ptr].cur_track;
|
|
|
|
if(!ad->xmlcheck)
|
|
{
|
|
hxcfe_pushSector(ad->fb);
|
|
|
|
hxcfe_setSectorHeadID(ad->fb,(unsigned char)(track&1));
|
|
hxcfe_setSectorTrackID(ad->fb,(unsigned char)(track>>1));
|
|
hxcfe_setSectorID(ad->fb,(unsigned char)sector);
|
|
hxcfe_setSectorSize(ad->fb,sectorsize);
|
|
if(ad->ts[track].base_adress + ad->ts[track].track_size + sectorsize <= ad->buffer_size)
|
|
{
|
|
hxcfe_setSectorData(ad->fb,&ad->image_data[ad->ts[track].base_adress + ad->ts[track].track_size],sectorsize);
|
|
}
|
|
}
|
|
|
|
ad->ts[track].track_size += sectorsize;
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XML_StopParser(ad->p, 0);
|
|
}
|
|
}
|
|
|
|
static void XMLCALL end(void *data, const char *el)
|
|
{
|
|
AppData *ad = (AppData *) data;
|
|
int state;
|
|
|
|
state = getstate((char*)el, ad->current_state);
|
|
|
|
if(!ad->xmlcheck)
|
|
{
|
|
|
|
switch(state)
|
|
{
|
|
case LAYOUT:
|
|
generateDisk(ad,ad->image_data,ad->buffer_size);
|
|
ad->floppy = hxcfe_getFloppy (ad->fb);
|
|
|
|
if(ad->interface_mode>=0)
|
|
hxcfe_floppySetInterfaceMode(ad->floppycontext,ad->floppy,ad->interface_mode);
|
|
|
|
if(ad->write_protect)
|
|
hxcfe_floppySetFlags(ad->floppycontext, ad->floppy, HXCFE_FLOPPY_WRPROTECTED_FLAG );
|
|
break;
|
|
|
|
case TRACK:
|
|
hxcfe_popTrack (ad->fb);
|
|
break;
|
|
|
|
case SECTOR:
|
|
if(ad->sector_data)
|
|
{
|
|
hxcfe_setSectorData(ad->fb,ad->sector_data,hxcfe_getCurrentSectorSize(ad->fb));
|
|
free(ad->sector_data);
|
|
ad->sector_data = 0;
|
|
ad->sector_data_offset = 0;
|
|
}
|
|
hxcfe_popSector(ad->fb);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(ad->stack_ptr)
|
|
{
|
|
ad->stack_ptr--;
|
|
}
|
|
|
|
ad->current_state = ad->statestack[ad->stack_ptr].state;
|
|
|
|
}
|
|
|
|
static void XMLCALL ns_start(void *data, const char *prefix, const char *uri)
|
|
{
|
|
|
|
}
|
|
|
|
static void XMLCALL ns_end( void *data, const char *prefix )
|
|
{
|
|
|
|
}
|
|
|
|
HXCFE_XMLLDR* hxcfe_initXmlFloppy( HXCFE* floppycontext )
|
|
{
|
|
AppData *ad;
|
|
HXCFE_XMLLDR * rfw;
|
|
int i;
|
|
|
|
rfw = malloc(sizeof(HXCFE_XMLLDR));
|
|
if(rfw)
|
|
{
|
|
memset(rfw,0,sizeof(HXCFE_XMLLDR));
|
|
|
|
rfw->xml_parser = XML_ParserCreate(NULL);
|
|
ad = malloc(sizeof(AppData));
|
|
if(!ad || !rfw->xml_parser)
|
|
{
|
|
free(ad);
|
|
XML_ParserFree(rfw->xml_parser);
|
|
free(rfw);
|
|
return 0;
|
|
}
|
|
|
|
memset(ad,0,sizeof(AppData));
|
|
|
|
ad->interface_mode = -1;
|
|
ad->min_nb_of_tracks = -1;
|
|
ad->max_nb_of_tracks = -1;
|
|
ad->nb_of_tracks = -1;
|
|
ad->file_size = -1;
|
|
|
|
ad->cur_index_number = 0;
|
|
ad->index_length = 0;
|
|
|
|
i=0;
|
|
while( disklayout_list[i])
|
|
{
|
|
if(disklayout_list[i]->unpacked_data)
|
|
{
|
|
free(disklayout_list[i]->unpacked_data);
|
|
disklayout_list[i]->unpacked_data = 0;
|
|
}
|
|
|
|
disklayout_list[i]->unpacked_data = data_unpack(disklayout_list[i]->data,disklayout_list[i]->csize,0,disklayout_list[i]->size);
|
|
i++;
|
|
}
|
|
|
|
ad->floppycontext = floppycontext;
|
|
ad->current_state = ENTRY_STATE;
|
|
ad->stack_ptr = 0;
|
|
memset(ad->statestack,0xFF,sizeof(int) * 32);
|
|
ad->statestack[0].state = ad->current_state;
|
|
ad->statestack[0].track_type = IBMFORMAT_DD;
|
|
ad->p = rfw->xml_parser;
|
|
|
|
memset(ad->ts,0,sizeof(track_state)*MAX_TRACKS_NB*2);
|
|
|
|
XML_ParserReset(rfw->xml_parser, NULL);
|
|
|
|
XML_SetUserData(rfw->xml_parser, (void *) ad);
|
|
XML_SetElementHandler(rfw->xml_parser, start, end);
|
|
|
|
XML_SetCharacterDataHandler(rfw->xml_parser, charhandler);
|
|
XML_SetNamespaceDeclHandler(rfw->xml_parser, ns_start, ns_end);
|
|
|
|
rfw->ad = ad;
|
|
}
|
|
|
|
return rfw;
|
|
}
|
|
|
|
void hxcfe_deinitXmlFloppy( HXCFE_XMLLDR* xmlfb_ctx )
|
|
{
|
|
int i;
|
|
|
|
XML_ParserFree(xmlfb_ctx->xml_parser);
|
|
|
|
i=0;
|
|
while( disklayout_list[i])
|
|
{
|
|
if(disklayout_list[i]->unpacked_data)
|
|
{
|
|
free(disklayout_list[i]->unpacked_data);
|
|
disklayout_list[i]->unpacked_data = 0;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
free(xmlfb_ctx);
|
|
}
|
|
|
|
int32_t hxcfe_getXmlLayoutID( HXCFE_XMLLDR* xmlfb_ctx, char * container )
|
|
{
|
|
int i;
|
|
AppData *ad = (AppData *) xmlfb_ctx->ad;
|
|
|
|
i = 0;
|
|
do
|
|
{
|
|
XML_ParserReset(xmlfb_ctx->xml_parser, NULL);
|
|
XML_SetUserData(xmlfb_ctx->xml_parser, (void *) ad);
|
|
XML_SetElementHandler(xmlfb_ctx->xml_parser, start, end);
|
|
XML_SetCharacterDataHandler(xmlfb_ctx->xml_parser, charhandler);
|
|
XML_SetNamespaceDeclHandler(xmlfb_ctx->xml_parser, ns_start, ns_end);
|
|
|
|
ad->xmlcheck = 1;
|
|
XML_Parse(xmlfb_ctx->xml_parser, (char*)disklayout_list[i]->unpacked_data, disklayout_list[i]->size, 1);
|
|
|
|
if(!strcmp((char*)ad->name,container))
|
|
{
|
|
return i;
|
|
}
|
|
|
|
memset(ad->name,0,512);
|
|
|
|
i++;
|
|
}while(disklayout_list[i]);
|
|
|
|
return -1;
|
|
}
|
|
|
|
const char* hxcfe_getXmlLayoutDesc( HXCFE_XMLLDR* xmlfb_ctx, int32_t moduleID )
|
|
{
|
|
AppData *ad = (AppData *) xmlfb_ctx->ad;
|
|
|
|
if(hxcfe_numberOfXmlLayout(xmlfb_ctx) > moduleID)
|
|
{
|
|
ad->xmlcheck = 1;
|
|
XML_ParserReset(xmlfb_ctx->xml_parser, NULL);
|
|
XML_SetUserData(xmlfb_ctx->xml_parser, (void *) ad);
|
|
XML_SetElementHandler(xmlfb_ctx->xml_parser, start, end);
|
|
XML_SetCharacterDataHandler(xmlfb_ctx->xml_parser, charhandler);
|
|
XML_SetNamespaceDeclHandler(xmlfb_ctx->xml_parser, ns_start, ns_end);
|
|
|
|
XML_Parse(xmlfb_ctx->xml_parser, (char*)disklayout_list[moduleID]->unpacked_data, disklayout_list[moduleID]->size, 1);
|
|
|
|
return (const char*)ad->description;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char* hxcfe_getXmlLayoutName( HXCFE_XMLLDR* xmlfb_ctx, int32_t moduleID )
|
|
{
|
|
AppData *ad = (AppData *) xmlfb_ctx->ad;
|
|
|
|
if(hxcfe_numberOfXmlLayout(xmlfb_ctx) > moduleID)
|
|
{
|
|
ad->xmlcheck = 1;
|
|
XML_ParserReset(xmlfb_ctx->xml_parser, NULL);
|
|
XML_SetUserData(xmlfb_ctx->xml_parser, (void *) ad);
|
|
XML_SetElementHandler(xmlfb_ctx->xml_parser, start, end);
|
|
XML_SetCharacterDataHandler(xmlfb_ctx->xml_parser, charhandler);
|
|
XML_SetNamespaceDeclHandler(xmlfb_ctx->xml_parser, ns_start, ns_end);
|
|
|
|
XML_Parse(xmlfb_ctx->xml_parser, (char*)disklayout_list[moduleID]->unpacked_data, disklayout_list[moduleID]->size, 1);
|
|
|
|
return (const char*)ad->name;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int32_t hxcfe_numberOfXmlLayout( HXCFE_XMLLDR* xmlfb_ctx )
|
|
{
|
|
int32_t i;
|
|
|
|
i = 0;
|
|
while( disklayout_list[i] )
|
|
{
|
|
i++;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
int32_t hxcfe_selectXmlFloppyLayout( HXCFE_XMLLDR* xmlfb_ctx, int32_t layoutid )
|
|
{
|
|
AppData *ad = (AppData *) xmlfb_ctx->ad;
|
|
|
|
if(hxcfe_numberOfXmlLayout(xmlfb_ctx) > layoutid)
|
|
{
|
|
memset((char*)&ad->xmlfile_path,0,sizeof(ad->xmlfile_path));
|
|
ad->layout_id = layoutid;
|
|
return HXCFE_NOERROR;
|
|
}
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
int32_t hxcfe_setXmlFloppyLayoutFile(HXCFE_XMLLDR* xmlfb_ctx,char * filepath)
|
|
{
|
|
char firstline[512];
|
|
FILE * f;
|
|
AppData *ad = (AppData *) xmlfb_ctx->ad;
|
|
|
|
if(hxc_checkfileext(filepath,"xml",SYS_PATH_TYPE))
|
|
{
|
|
f = hxc_fopen(filepath,"rb");
|
|
if( f )
|
|
{
|
|
memset(firstline,0,sizeof(firstline));
|
|
hxc_fgets(firstline,sizeof(firstline)-1,f);
|
|
hxc_fclose(f);
|
|
|
|
if(strstr(firstline,"<?xml version="))
|
|
{
|
|
strcpy((char*)&ad->xmlfile_path,filepath);
|
|
ad->layout_id = -1;
|
|
ad->floppycontext->hxc_printf(MSG_DEBUG,"hxcfe_setXmlFloppyLayoutFile : XML file !");
|
|
return HXCFE_NOERROR;
|
|
}
|
|
|
|
ad->floppycontext->hxc_printf(MSG_DEBUG,"hxcfe_setXmlFloppyLayoutFile : non XML file !");
|
|
return HXCFE_BADFILE;
|
|
}
|
|
}
|
|
|
|
return HXCFE_BADPARAMETER;
|
|
}
|
|
|
|
|
|
HXCFE_FLOPPY* hxcfe_generateXmlFloppy ( HXCFE_XMLLDR* xmlfb_ctx, uint8_t * rambuffer, uint32_t buffersize )
|
|
{
|
|
AppData *ad;
|
|
FILE *f;
|
|
int filesize;
|
|
char * xmlbuffer;
|
|
|
|
ad = xmlfb_ctx->ad;
|
|
|
|
ad->xmlcheck = 0;
|
|
|
|
ad->image_data = rambuffer;
|
|
ad->buffer_size = buffersize;
|
|
|
|
memset(ad->ts,0,sizeof(track_state)*MAX_TRACKS_NB*2);
|
|
|
|
XML_ParserReset(xmlfb_ctx->xml_parser, NULL);
|
|
XML_SetUserData(xmlfb_ctx->xml_parser, (void *) ad);
|
|
XML_SetElementHandler(xmlfb_ctx->xml_parser, start, end);
|
|
XML_SetCharacterDataHandler(xmlfb_ctx->xml_parser, charhandler);
|
|
XML_SetNamespaceDeclHandler(xmlfb_ctx->xml_parser, ns_start, ns_end);
|
|
|
|
if(ad->layout_id!=-1)
|
|
{
|
|
XML_Parse(xmlfb_ctx->xml_parser, (char*)disklayout_list[ad->layout_id]->unpacked_data, disklayout_list[ad->layout_id]->size, 1);
|
|
}
|
|
else
|
|
{
|
|
ad->floppy = 0;
|
|
|
|
f = hxc_fopen((char*)ad->xmlfile_path,"rb");
|
|
if(f)
|
|
{
|
|
filesize = hxc_fgetsize(f);
|
|
if(filesize>0)
|
|
{
|
|
xmlbuffer = malloc(filesize + 1);
|
|
if(xmlbuffer)
|
|
{
|
|
memset(xmlbuffer,0,filesize + 1);
|
|
hxc_fread(xmlbuffer,filesize,f);
|
|
|
|
XML_Parse(xmlfb_ctx->xml_parser, xmlbuffer, filesize, 1);
|
|
|
|
free(xmlbuffer);
|
|
}
|
|
}
|
|
|
|
hxc_fclose(f);
|
|
}
|
|
}
|
|
|
|
return ad->floppy;
|
|
}
|
|
|
|
static int is_size_matching( HXCFE_XMLLDR* xmlfb_ctx, int image_size)
|
|
{
|
|
AppData *ad;
|
|
int i;
|
|
int track_min;
|
|
int track_max;
|
|
int total_size;
|
|
|
|
ad = xmlfb_ctx->ad;
|
|
|
|
track_min = ad->nb_of_tracks;
|
|
track_max = ad->nb_of_tracks;
|
|
|
|
if( ad->min_nb_of_tracks != -1 )
|
|
track_min = ad->min_nb_of_tracks;
|
|
|
|
if( ad->max_nb_of_tracks != -1 )
|
|
track_max = ad->max_nb_of_tracks;
|
|
|
|
for( i = 0; i < track_max * 2 ; i++)
|
|
{
|
|
if(!ad->ts[i].set)
|
|
{
|
|
ad->ts[i].track_size = ad->nb_sectors_per_track * ad->sector_size;
|
|
ad->ts[i].set = 1;
|
|
}
|
|
}
|
|
|
|
i = 0;
|
|
total_size = 0;
|
|
while(i < track_min * 2 )
|
|
{
|
|
total_size += ad->ts[i].track_size;
|
|
i++;
|
|
|
|
if(ad->nb_of_sides == 2)
|
|
total_size += ad->ts[i].track_size;
|
|
i++;
|
|
}
|
|
|
|
for( i = track_min * 2; i <= track_max * 2; i += 2 )
|
|
{
|
|
total_size += ad->ts[i].track_size;
|
|
|
|
if(ad->nb_of_sides == 2)
|
|
total_size += ad->ts[i+1].track_size;
|
|
|
|
if( total_size == image_size )
|
|
{
|
|
return i / 2;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int32_t hxcfe_isMatchingXmlFloppy ( HXCFE_XMLLDR* xmlfb_ctx, char * filename, uint8_t * rambuffer, uint32_t buffersize )
|
|
{
|
|
AppData *ad;
|
|
FILE *f;
|
|
int filesize;
|
|
char * xmlbuffer;
|
|
|
|
ad = xmlfb_ctx->ad;
|
|
|
|
ad->xmlcheck = 1;
|
|
|
|
ad->image_data = rambuffer;
|
|
ad->buffer_size = buffersize;
|
|
|
|
memset(ad->ts,0,sizeof(track_state)*MAX_TRACKS_NB*2);
|
|
|
|
XML_ParserReset(xmlfb_ctx->xml_parser, NULL);
|
|
XML_SetUserData(xmlfb_ctx->xml_parser, (void *) ad);
|
|
XML_SetElementHandler(xmlfb_ctx->xml_parser, start, end);
|
|
XML_SetCharacterDataHandler(xmlfb_ctx->xml_parser, charhandler);
|
|
XML_SetNamespaceDeclHandler(xmlfb_ctx->xml_parser, ns_start, ns_end);
|
|
|
|
if(ad->layout_id!=-1)
|
|
{
|
|
XML_Parse(xmlfb_ctx->xml_parser, (char*)disklayout_list[ad->layout_id]->unpacked_data, disklayout_list[ad->layout_id]->size, 1);
|
|
}
|
|
else
|
|
{
|
|
ad->floppy = 0;
|
|
|
|
f = hxc_fopen((char*)ad->xmlfile_path,"rb");
|
|
if(f)
|
|
{
|
|
filesize = hxc_fgetsize(f);
|
|
if(filesize>0)
|
|
{
|
|
xmlbuffer = malloc(filesize + 1);
|
|
if(xmlbuffer)
|
|
{
|
|
memset(xmlbuffer,0,filesize + 1);
|
|
hxc_fread(xmlbuffer,filesize,f);
|
|
|
|
XML_Parse(xmlfb_ctx->xml_parser, xmlbuffer, filesize, 1);
|
|
|
|
free(xmlbuffer);
|
|
}
|
|
}
|
|
|
|
hxc_fclose(f);
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// Check image.
|
|
|
|
// Check file size
|
|
if( ad->file_size != -1 )
|
|
{
|
|
if( buffersize != (uint32_t)ad->file_size )
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check file extension(s).
|
|
if(filename)
|
|
{
|
|
if( strlen( ad->file_extensions ) && strlen( filename ) )
|
|
{
|
|
if ( !is_ext_matching( filename, ad->file_extensions ) )
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check total raw sectors size
|
|
if ( !is_size_matching( xmlfb_ctx, buffersize ) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
HXCFE_FLOPPY* hxcfe_generateXmlFileFloppy (HXCFE_XMLLDR* xmlfb_ctx,char *file)
|
|
{
|
|
FILE * f;
|
|
unsigned int filesize;
|
|
HXCFE_FLOPPY* ret;
|
|
unsigned char * buffer;
|
|
|
|
ret = 0;
|
|
f = hxc_fopen(file,"rb");
|
|
if(f)
|
|
{
|
|
filesize = hxc_fgetsize(f);
|
|
|
|
if(filesize)
|
|
{
|
|
if(filesize > 32*1024*1024)
|
|
{
|
|
filesize = 32*1024*1024;
|
|
}
|
|
|
|
buffer = malloc(filesize);
|
|
if(buffer)
|
|
{
|
|
memset(buffer,0,filesize);
|
|
|
|
hxc_fread(buffer, filesize, f);
|
|
|
|
ret = hxcfe_generateXmlFloppy (xmlfb_ctx,buffer,filesize);
|
|
|
|
free(buffer);
|
|
}
|
|
}
|
|
|
|
hxc_fclose(f);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int32_t hxcfe_foundMatchingXmlFileFloppy (HXCFE_XMLLDR* xmlfb_ctx,char *file)
|
|
{
|
|
FILE * f;
|
|
unsigned int filesize,i,number_of_layout;
|
|
int32_t ret;
|
|
unsigned char * buffer;
|
|
|
|
ret = HXCFE_UNSUPPORTEDFILE;
|
|
|
|
f = hxc_fopen(file,"rb");
|
|
if(f)
|
|
{
|
|
filesize = hxc_fgetsize(f);
|
|
|
|
if(filesize)
|
|
{
|
|
if(filesize > 32*1024*1024)
|
|
{
|
|
filesize = 32*1024*1024;
|
|
}
|
|
|
|
buffer = malloc(filesize);
|
|
if(buffer)
|
|
{
|
|
memset(buffer,0,filesize);
|
|
|
|
hxc_fread(buffer, filesize, f);
|
|
|
|
number_of_layout = hxcfe_numberOfXmlLayout( xmlfb_ctx );
|
|
|
|
i = 0;
|
|
while( i < number_of_layout)
|
|
{
|
|
if( hxcfe_selectXmlFloppyLayout( xmlfb_ctx, i ) == HXCFE_NOERROR )
|
|
{
|
|
ret = hxcfe_isMatchingXmlFloppy(xmlfb_ctx,file,buffer,filesize);
|
|
|
|
if( ret > 0 )
|
|
{
|
|
free(buffer);
|
|
hxc_fclose(f);
|
|
return i;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
|
|
free(buffer);
|
|
}
|
|
}
|
|
|
|
hxc_fclose(f);
|
|
}
|
|
|
|
return ret;
|
|
}
|