Exemplo n.º 1
0
int infofile(HXCFLOPPYEMULATOR* hxcfe,char * infile)
{
	int loaderid;
	int ret;
	FLOPPY * floppydisk;
	int ifmode,nbofsector;

	printf("---------------------------------------------------------------------------\n");
	printf("-                        File informations                                -\n");
	printf("---------------------------------------------------------------------------\n");

	printf("File: %s\n",infile);

	loaderid=hxcfe_autoSelectLoader(hxcfe,infile,0);
	if(loaderid>=0)
	{
		floppydisk=hxcfe_floppyLoad(hxcfe,infile,loaderid,&ret);
				
		if(ret!=HXCFE_NOERROR || !floppydisk)
		{
			switch(ret)
			{
				case HXCFE_UNSUPPORTEDFILE:
					printf("Load error!: Image file not yet supported!\n");
				break;
				case HXCFE_FILECORRUPTED:
					printf("Load error!: File corrupted ? Read error ?\n");
				break;
				case HXCFE_ACCESSERROR:
					printf("Load error!:  Read file error!\n");
				break;
				default:
					printf("Load error! error %d\n",ret);
				break;
			}
		}
		else
		{
			ifmode=hxcfe_floppyGetInterfaceMode(hxcfe,floppydisk);
			printf("\n");
			printf("File type : %s - %s\n",hxcfe_getLoaderName(hxcfe,loaderid),hxcfe_getLoaderDesc(hxcfe,loaderid));
			printf("Floppy interface mode : %s\n",hxcfe_getFloppyInterfaceModeName(hxcfe,ifmode),hxcfe_getFloppyInterfaceModeDesc(hxcfe,ifmode));
			printf("Number of Track : %d\n",hxcfe_getNumberOfTrack(hxcfe,floppydisk) );
			printf("Number of Side : %d\n",hxcfe_getNumberOfSide(hxcfe,floppydisk) );
			printf("Total Size : %d Bytes, ",hxcfe_getFloppySize (hxcfe,floppydisk,&nbofsector)); 
			printf("Number of sectors : %d",nbofsector); 

			ifmode=hxcfe_floppyGetInterfaceMode(hxcfe,floppydisk);

			//loaderid=hxcfe_getLoaderID(hxcfe,outformat);

			hxcfe_floppyUnload(hxcfe,floppydisk);

			printf("\n");
		}
	}

	return 0;
}
Exemplo n.º 2
0
void BCConvert(HWND dlg)
// performs the batch conversion on selected files
// TODO: progress dialogue, option to cancel process
//		see SHFileOperation for recycle bin ops, write seperate fn.
{
	int		count;
	int		i, j, iLength;
	char	inBuf[MAX_PATH];
	char	outBuf[MAX_PATH];
	char	statusBuf[MAX_PATH];
	char	FileRoot[MAX_PATH];
	char	FileSuf[4];
	char	fileName[MAX_PATH];
	HWND	fl = GetDlgItem(dlg, IDC_BCFILELIST);
	HWND	sl = GetDlgItem(dlg, IDC_BCSTATUS);
	
	int side,track,nbsect,image_size;
	HXCFE * hxcfe;
	HXCFE_FLOPPY* fp;
	HXCFE_SECTORACCESS* ss;
	HXCFE_IMGLDR * imgldr_ctx;
	int loaderId;
	unsigned char * floppybuffer;
	FILE * f;

	LRESULT	State_ADZ;
	LRESULT	State_ADF;
	LRESULT	State_HFE;

	HANDLE	hFile;
	BOOL	bUsingTemp = FALSE;		// TRUE if using temp directory for intermediate file.
	USHORT	dmsError;
//	char	dmsErrorMessage[MAX_PATH];
	BOOL	bOverwriting = TRUE;


	count = SendMessage(fl, LB_GETCOUNT, 0, 0l);
	
	for (i = 0 ; i < count ; i++) {
		SendMessage(fl, LB_GETTEXT, 0, (LPARAM)&inBuf);		// Get filename from list.

		UpdateWindow(dlg);

		strcpy(outBuf, inBuf);

		iLength = strlen(inBuf);						// Get name length.
		for(j = 0;j < iLength - 3;j++)					// Get name root.
			FileRoot[j] = inBuf[j];
		FileRoot[j] = '\0';

		FileSuf[0] = inBuf[iLength - 3];				// Get name suffix.
		FileSuf[1] = inBuf[iLength - 2];
		FileSuf[2] = inBuf[iLength - 1];
		FileSuf[3] = '\0';
		
		strcpy(outBuf, FileRoot);						// Set the outfile name root.
	
		// Get the check state of the output buttons.
		State_ADZ = SendMessage(GetDlgItem(dlg, IDC_BCADZ), BM_GETSTATE, 0, 0);
		State_ADF = SendMessage(GetDlgItem(dlg, IDC_BCADF), BM_GETSTATE, 0, 0);
		State_HFE = SendMessage(GetDlgItem(dlg, IDC_BCHFE), BM_GETSTATE, 0, 0);

		// if hfe.
		if(strcmp(FileSuf, "hfe") == 0 || strcmp(FileSuf, "HFE") == 0 ){
			// Print decompression status message.
			sprintf(statusBuf, "Unpacking file '%s'...", inBuf);	

			// If dms to adz, use temp directory.
			if(State_ADZ & BST_CHECKED){
				_splitpath(strOFNFileNames, NULL, NULL, fileName, NULL);	// Get filename.
				strcpy(outBuf, dirTemp);
				strcat(outBuf, fileName);
				strcat(outBuf, ".");
				bUsingTemp = TRUE;						// Using temp dir.
			}
			
			strcat(outBuf, "adf");						// Set the outfile name suffix.
			SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);

			// Check for file overwrite.
			hFile = CreateFile(outBuf, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
			// If file exists and we're not writing to temp dir, ask.
			if(hFile != INVALID_HANDLE_VALUE && !bUsingTemp){
				sprintf(statusBuf, "The file %s already exists.\n Do you want to overwrite this file?", outBuf);
				// Set bool if not overwriting.
				if(MessageBox(dlg, statusBuf, "ADF Opus Warning", MB_YESNO|MB_ICONEXCLAMATION) == IDNO){
					bOverwriting = FALSE;
				}
			}

			if(bOverwriting){
			// Overwrite.
				// Open HFE
				hxcfe =  hxcfe_init();
				imgldr_ctx = hxcfe_imgInitLoader(hxcfe);
				loaderId = hxcfe_imgGetLoaderID(imgldr_ctx,"HXC_HFE");
				fp = hxcfe_imgLoad(imgldr_ctx,(char*)inBuf,loaderId,0);
				if(fp)
				{
					image_size = hxcfe_getFloppySize(hxcfe,fp,0);

					if(image_size)
					{
						floppybuffer=(char*)malloc(image_size);

						nbsect=11;
						switch(image_size)
						{
							case 80*11*2*512:
								nbsect=11;
							break;
							case 80*22*2*512:
								nbsect=22;
							break;
						}

						ss = hxcfe_initSectorAccess(hxcfe,fp);

						for(track=0;track<hxcfe_getNumberOfTrack(hxcfe,fp);track++)
						{
							for(side=0;side<hxcfe_getNumberOfSide(hxcfe,fp);side++)
							{
								hxcfe_readSectorData(ss,track,side,0,nbsect,512,AMIGA_MFM_ENCODING,&floppybuffer[(512*nbsect)*((track*hxcfe_getNumberOfSide(hxcfe,fp))+side)],0);
							}
						}
							
						hxcfe_deinitSectorAccess(ss);

						hxcfe_imgUnload(imgldr_ctx,fp);

						hxcfe_imgDeInitLoader(imgldr_ctx);
						hxcfe_deinit(hxcfe);
							
						f=fopen(outBuf,"wb");
						if(f)
						{
							fwrite(floppybuffer,image_size,1,f);
							fclose(f);
						}
						
						free(floppybuffer);

						strcpy(statusBuf, "...file loaded successfully.");
					}

				}
				else
				{
					hxcfe_deinit(hxcfe);
					strcpy(statusBuf, "...error occured during HFE Loading.");
				}
			}
			else{
				// Abort
				strcpy(statusBuf, "...aborted to avoid overwrite.");
				SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);
			}
		}
		
		// if dms.				 
		if(strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0 ){
			// Print decompression status message.
			sprintf(statusBuf, "Unpacking file '%s'...", inBuf);	

			// If dms to adz, use temp directory.
			if(State_ADZ & BST_CHECKED){
				_splitpath(strOFNFileNames, NULL, NULL, fileName, NULL);	// Get filename.
				strcpy(outBuf, dirTemp);
				strcat(outBuf, fileName);
				strcat(outBuf, ".");
				bUsingTemp = TRUE;						// Using temp dir.
			}
			
			strcat(outBuf, "adf");						// Set the outfile name suffix.
			SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);

			// Check for file overwrite.
			hFile = CreateFile(outBuf, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
			// If file exists and we're not writing to temp dir, ask.
			if(hFile != INVALID_HANDLE_VALUE && !bUsingTemp){
				sprintf(statusBuf, "The file %s already exists.\n Do you want to overwrite this file?", outBuf);
				// Set bool if not overwriting.
				if(MessageBox(dlg, statusBuf, "ADF Opus Warning", MB_YESNO|MB_ICONEXCLAMATION) == IDNO){
					bOverwriting = FALSE;
				}
			}

			if(bOverwriting){
			// Overwrite.
				if(dmsError = dmsUnpack(inBuf, outBuf) == NO_PROBLEM)	// Decompress.
					strcpy(statusBuf, "...file unpacked successfully.");
				else
					strcpy(statusBuf, "...error occured during DMS decompression.");
			}
			else{
				// Abort
				strcpy(statusBuf, "...aborted to avoid overwrite.");

// ************************** TRYING TO ACCESS DMS ERRORS IN XDMS.C - WON'T COMPILE
//				dmsErrMsg(dmsError, inBuf, outBuf, dmsErrorMessage);
//				strcat(statusBuf, dmsErrorMessage);
				SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);
			}
		}
		

		//if adz and adf button selected.
		if((strcmp(FileSuf, "adz") == 0 || strcmp(FileSuf, "ADZ") == 0) && (State_ADF & BST_CHECKED) ){
			// Print decompression status message.
			sprintf(statusBuf, "Unpacking file '%s'...", inBuf);	
			strcat(outBuf, "adf");						// Set the outfile name suffix.
			SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);

			if(GZDecompress(dlg, inBuf, outBuf))
				strcpy(statusBuf, "...file unpacked successfully.");
			else
				strcpy(statusBuf, "...failed to unpack file.");
		}

		//if adf or decompressed dms and adz button selected.
		if(
			(   ( strcmp(FileSuf, "adf") == 0 || strcmp(FileSuf, "ADF") == 0 ) 
			||  ( strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0 ) ) 
			&&  (State_ADZ & BST_CHECKED) )
		{
			
			// If recompressing an adf'd dms, remove the suffixes and
			// write last status message.
			if(strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0){
				SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);	
				strcpy(inBuf, outBuf);
				strcpy(outBuf, FileRoot);
			}

			// Print compression status message.
			sprintf(statusBuf, "Compressing file '%s'...", inBuf);	

			strcat(outBuf, "adz");						// Set the outfile name suffix.
			SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);

			if(GZCompress(dlg, inBuf, outBuf))
				strcpy(statusBuf, "...file compressed successfully.");
			else
				strcpy(statusBuf, "...failed to compress file.");

			// Delete intermediate adf.
			if(strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0)
				remove(inBuf);
		}


		// hfe button selected.
		if(  ( ( strcmp(FileSuf, "adf") == 0 || strcmp(FileSuf, "ADF") == 0 )
			|| ( strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0 ) 
			|| ( strcmp(FileSuf, "adz") == 0 || strcmp(FileSuf, "ADZ") == 0 ) )
			&& (State_HFE & BST_CHECKED) ){
			
			// If recompressing an adf'd dms, remove the suffixes and
			// write last status message.
			if(strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0){
				SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);	
				strcpy(inBuf, outBuf);
				strcpy(outBuf, FileRoot);
			}

			// Print compression status message.
			sprintf(statusBuf, "Compressing file '%s'...", inBuf);	

			strcat(outBuf, "hfe");						// Set the outfile name suffix.
			SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);

			hxcfe=hxcfe_init();
			imgldr_ctx = hxcfe_imgInitLoader(hxcfe);

			fp=0;
			loaderId = hxcfe_imgAutoSetectLoader(imgldr_ctx,inBuf,0);
			// Load the image
			if(loaderId>=0)
				fp = hxcfe_imgLoad(imgldr_ctx,inBuf,loaderId,0);
			if(fp)
			{
				// Select the HFE loader/exporter.
				loaderId=hxcfe_imgGetLoaderID(imgldr_ctx,"HXC_HFE");
				// Save the file...
				hxcfe_imgExport(imgldr_ctx,fp,outBuf,loaderId);
				// Free the loaded image
				hxcfe_imgUnload(imgldr_ctx,fp);
				strcpy(statusBuf, "...file compressed successfully.");
			}
			else
			{
				strcpy(statusBuf, "...failed to compress file.");
			}

			hxcfe_imgDeInitLoader(imgldr_ctx);
			hxcfe_deinit(hxcfe);

			// Delete intermediate adf.
			if(strcmp(FileSuf, "dms") == 0 || strcmp(FileSuf, "DMS") == 0)
				remove(inBuf);
		}
		//no dms compression at this stage.

		SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);		// Write final status message.
		SendMessage(fl, LB_DELETESTRING, 0, 0l);					// Delete file from lister. 
		bUsingTemp = FALSE;											// Reset temp dir flag.

		if(SendDlgItemMessage(dlg, IDC_BCDELETE_ORIGINAL, BM_GETCHECK, 0, 0L) == BST_CHECKED){
		//Delete the original file.
			remove(inBuf);
			sprintf(statusBuf, "Deleted %s.", inBuf);
			SendMessage(sl, LB_ADDSTRING, 0, (LPARAM)&statusBuf);	// Write deletion message.
		}
	}
	// Write a divider line to improve readability.
	SendMessage(sl, LB_ADDSTRING, 0, 
		(LPARAM)"----------------------------------------------------------------------------------------------");

	// Re-enable output buttons once operations are complete.
	SendMessage(GetDlgItem(dlg, IDC_BCADF), BM_SETCHECK, BST_CHECKED, 0);
	SendMessage(GetDlgItem(dlg, IDC_BCADZ), BM_SETCHECK, BST_UNCHECKED, 0);
	SendMessage(GetDlgItem(dlg, IDC_BCHFE), BM_SETCHECK, BST_UNCHECKED, 0);
	EnableWindow(GetDlgItem(dlg, IDC_BCADF), TRUE);
	EnableWindow(GetDlgItem(dlg, IDC_BCADZ), TRUE);
	EnableWindow(GetDlgItem(dlg, IDC_BCHFE), TRUE);

	BCUpdateButtons(dlg);						// Dis/enable buttons.
}
Exemplo n.º 3
0
int imagedir(HXCFLOPPYEMULATOR* hxcfe,char * infile)
{
	int loaderid;
	int ret;
	FLOPPY * floppydisk;
	int ifmode,nbofsector;
	FSMNG  * fsmng;

	printf("---------------------------------------------------------------------------\n");
	printf("-                        File image browser                               -\n");
	printf("---------------------------------------------------------------------------\n");

	printf("File: %s\n",infile);

	loaderid=hxcfe_autoSelectLoader(hxcfe,infile,0);
	if(loaderid>=0)
	{
		floppydisk=hxcfe_floppyLoad(hxcfe,infile,loaderid,&ret);
				
		if(ret!=HXCFE_NOERROR || !floppydisk)
		{
			switch(ret)
			{
				case HXCFE_UNSUPPORTEDFILE:
					printf("Load error!: Image file not yet supported!\n");
				break;
				case HXCFE_FILECORRUPTED:
					printf("Load error!: File corrupted ? Read error ?\n");
				break;
				case HXCFE_ACCESSERROR:
					printf("Load error!:  Read file error!\n");
				break;
				default:
					printf("Load error! error %d\n",ret);
				break;
			}
		}
		else
		{
			ifmode=hxcfe_floppyGetInterfaceMode(hxcfe,floppydisk);
			printf("\n");
			printf("File type : %s - %s\n",hxcfe_getLoaderName(hxcfe,loaderid),hxcfe_getLoaderDesc(hxcfe,loaderid));
			printf("Floppy interface mode : %s\n",hxcfe_getFloppyInterfaceModeName(hxcfe,ifmode),hxcfe_getFloppyInterfaceModeDesc(hxcfe,ifmode));
			printf("Number of Track : %d\n",hxcfe_getNumberOfTrack(hxcfe,floppydisk) );
			printf("Number of Side : %d\n",hxcfe_getNumberOfSide(hxcfe,floppydisk) );
			printf("Total Size : %d Bytes, ",hxcfe_getFloppySize (hxcfe,floppydisk,&nbofsector)); 
			printf("Number of sectors : %d\n",nbofsector); 

			ifmode=hxcfe_floppyGetInterfaceMode(hxcfe,floppydisk);

			printf("\n------- Disk Tree --------\n"); 
			fsmng = hxcfe_initFsManager(hxcfe);
			if (fsmng)
			{
				hxcfe_selectFS(fsmng, 0);
				hxcfe_mountImage(fsmng, floppydisk);

				displaydir(fsmng,"/",0);
				hxcfe_deinitFsManager(fsmng);
			}
			hxcfe_floppyUnload(hxcfe,floppydisk);

			printf("\n--------------------------\n"); 
		}
	}

	return 0;
}
Exemplo n.º 4
0
int XML_libWrite_DiskFile(HXCFLOPPYEMULATOR* floppycontext,FLOPPY * floppy,char * filename)
{
	int i,j,k,s;
	FILE * xmlfile;
	int fileoffset,nb_sectorfound;
	int nbsect,firstsectid,sectorsize,imagesize;
	char trackformat[32];
	SECTORSEARCH* ss;
	SECTORCONFIG** sca;
	sect_offset ** sorted_sectoffset,**sectoffset;

	floppycontext->hxc_printf(MSG_INFO_1,"Write XML file %s...",filename);

	fileoffset = 0;

	xmlfile=hxc_fopen(filename,"w+");
	if(xmlfile)
	{
		imagesize = hxcfe_getFloppySize(floppycontext,floppy,0);

		ss=hxcfe_initSectorSearch(floppycontext,floppy);
		if(ss)
		{
			fprintf(xmlfile,"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
			fprintf(xmlfile,"<!-- HxC Floppy Emulator Disk Layout -->\n");

			fprintf(xmlfile,"<disk_layout>\n");

			fprintf(xmlfile,"\t<disk_layout_name>AUTOGENERATEDLAYOUT</disk_layout_name>\n");
			fprintf(xmlfile,"\t<disk_layout_description>Auto Generated Disk Layout</disk_layout_description>\n");
			fprintf(xmlfile,"\t<prefered_file_extension>img</prefered_file_extension>\n");
			fprintf(xmlfile,"\t<interface_mode>GENERIC_SHUGART_DD_FLOPPYMODE</interface_mode>\n");

			fprintf(xmlfile,"\t<file_size>%d</file_size>\n",imagesize);

			fprintf(xmlfile,"\t<layout>\n");

			fprintf(xmlfile,"\t\t<number_of_track>%d</number_of_track>\n",floppy->floppyNumberOfTrack);
			fprintf(xmlfile,"\t\t<number_of_side>%d</number_of_side>\n",floppy->floppyNumberOfSide);

			gettracktype(ss,0,0,&nbsect,&firstsectid,(char*)&trackformat,&sectorsize);

			fprintf(xmlfile,"\t\t<format>%s</format>\n",trackformat);

			fprintf(xmlfile,"\t\t<start_sector_id>%d</start_sector_id>\n",firstsectid);
			fprintf(xmlfile,"\t\t<sector_per_track>%d</sector_per_track>\n",nbsect);

			fprintf(xmlfile,"\t\t<sector_size>%d</sector_size>\n",sectorsize);

			fprintf(xmlfile,"\t\t<formatvalue>%d</formatvalue>\n",0x00);

			fprintf(xmlfile,"\t\t<gap3>%d</gap3>\n",0xFF);

			fprintf(xmlfile,"\t\t<bitrate>%d</bitrate>\n",floppy->floppyBitRate);
			fprintf(xmlfile,"\t\t<pregap>%d</pregap>\n",0);
			fprintf(xmlfile,"\t\t<rpm>%d</rpm>\n",floppy->tracks[0]->floppyRPM);

			fprintf(xmlfile,"\t\t<track_list>\n");


			for(j=0;j<floppy->floppyNumberOfTrack;j++)
			{
				for(i=0;i<floppy->floppyNumberOfSide;i++)
				{
					fprintf(xmlfile,"\t\t\t<track track_number=\"%.2d\" side_number=\"%d\">\n",j,i);
					fprintf(xmlfile,"\t\t\t\t<data_offset>0x%.6X</data_offset>\n",fileoffset);

					gettracktype(ss,j,i,&nbsect,&firstsectid,(char*)&trackformat,&sectorsize);
					fprintf(xmlfile,"\t\t\t\t<format>%s</format>\n",trackformat);

					sca = hxcfe_getAllTrackISOSectors(ss,j,i,&nb_sectorfound);
					fprintf(xmlfile,"\t\t\t\t<sector_list>\n");

					if(sca && nb_sectorfound)
					{
						sectoffset = malloc(sizeof(sect_offset*) * nb_sectorfound);
						sorted_sectoffset = malloc(sizeof(sect_offset*) * nb_sectorfound);
						if(sorted_sectoffset && sectoffset)
						{
							memset(sectoffset,0,sizeof(sect_offset*) * nb_sectorfound);
							memset(sorted_sectoffset,0,sizeof(sect_offset*) * nb_sectorfound);
							for(s=0;s<nb_sectorfound;s++)
							{
								sorted_sectoffset[s] = malloc(sizeof(sect_offset));
								sorted_sectoffset[s]->ss = sca[s];
								sorted_sectoffset[s]->offset = 0;
							}

							memcpy(sectoffset,sorted_sectoffset,sizeof(sect_offset*) * nb_sectorfound);

							quickSort(sorted_sectoffset, 0, nb_sectorfound - 1);

							for(s=0;s<nb_sectorfound;s++)
							{
								sorted_sectoffset[s]->offset = fileoffset;
								fileoffset += sca[s]->sectorsize;
							}

							free(sorted_sectoffset);

							for(s=0;s<nb_sectorfound;s++)
							{

								fprintf(xmlfile,"\t\t\t\t\t<sector sector_id=\"%d\" sector_size=\"%d\">\n",sca[s]->sector,sca[s]->sectorsize);
								if(sca[s]->fill_byte_used)
								{
									fprintf(xmlfile,"\t\t\t\t\t\t<data_fill>0x%.2X</data_fill>\n",sca[s]->fill_byte);
								}
								else
								{
									if(sca[s]->input_data)
									{
										fprintf(xmlfile,"\t\t\t\t\t\t<sector_data>");
										k=0;
										do
										{
											fprintf(xmlfile,"%.2X",sca[s]->input_data[k]);
											k++;
										}while(k<(int)sca[s]->sectorsize);

										fprintf(xmlfile,"</sector_data>\n");
									}
								}

								if(sca[s]->use_alternate_datamark)
								{
									fprintf(xmlfile,"\t\t\t\t\t\t<datamark>0x%.2X</datamark>\n",sca[s]->alternate_datamark);
								}

								fprintf(xmlfile,"\t\t\t\t\t\t<data_offset>0x%.6X</data_offset>\n",(unsigned int)sectoffset[s]->offset);
								fprintf(xmlfile,"\t\t\t\t\t</sector>\n");

								hxcfe_freeSectorConfig  (ss,sca[s]);
							}

							for(s=0;s<nb_sectorfound;s++)
							{
								free(sectoffset[s]);
							}
							free(sectoffset);
						}

						free(sca);
					}

					fprintf(xmlfile,"\t\t\t\t</sector_list>\n");

					fprintf(xmlfile,"\t\t\t</track>\n");
				}
			}
			hxcfe_deinitSectorSearch(ss);
		}

		fprintf(xmlfile,"\t\t</track_list>\n");
		fprintf(xmlfile,"\t</layout>\n");
		fprintf(xmlfile,"</disk_layout>\n");

		hxc_fclose(xmlfile);
	}

	return 0;
}
int TI99V9T9_libWrite_DiskFile(HXCFE_IMGLDR* imgldr_ctx,HXCFE_FLOPPY * floppy,char * filename)
{
	int i,j,k;
	FILE * ti99v9t9file;
	int32_t nbsector,imagesize;

	int32_t numberofsector,numberofside,numberoftrack;
	int32_t density = ISOIBM_FM_ENCODING;
	int file_offset;
	int32_t sectorsize = 256;
	unsigned char * diskimage;
	int error = 0;
	HXCFE_SECTORACCESS* ss;
	HXCFE_SECTCFG* sc;

	imgldr_ctx->hxcfe->hxc_printf(MSG_INFO_1,"Write TI99 V9T9 file %s...",filename);

	imagesize=hxcfe_getFloppySize(imgldr_ctx->hxcfe,floppy,&nbsector);

	imgldr_ctx->hxcfe->hxc_printf(MSG_INFO_1,"Disk size : %d Bytes %d Sectors",imagesize,nbsector);

	ss = hxcfe_initSectorAccess(imgldr_ctx->hxcfe, floppy);
	if (ss)
	{
		sc = hxcfe_searchSector(ss, 0, 0, 0, density);
		if (!sc)
		{
			density = ISOIBM_MFM_ENCODING;
			sc = hxcfe_searchSector(ss, 0, 0, 0, density);
			if (!sc)
			{
				imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR, "This disk is neither FM nor MFM.  Exiting.");
				return HXCFE_FILECORRUPTED;
			}
		}

		// sc->input_data should contain the disk geometry

		numberofside = sc->input_data[0x12];
		numberofsector = sc->input_data[0x0c];
		numberoftrack = sc->input_data[0x11];

		if ( (numberofside < 1) && (numberofside > 2))
		{
			imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR, "Image claims it has %i sides, which is clearly wrong.  Exiting.", numberofside);
			return HXCFE_FILECORRUPTED;
		}
 
		if ( (numberoftrack != 40) && (numberoftrack != 80))
		{
			imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR, "Image claims each side has %i tracks, which is clearly wrong.  Exiting.", numberoftrack);
			return HXCFE_FILECORRUPTED;
		}
 
		if ( (numberofsector != 9) && (numberofsector != 16) && (numberofsector != 18) && (numberofsector != 36))
		{
			imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR, "Image claims each track has %i sectors, which is clearly wrong.  Exiting.", numberofsector);
			return HXCFE_FILECORRUPTED;
		}

		if ( (numberofsector * numberoftrack * numberofside) != nbsector )
		{
			imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR, "Disk geometry %i/%i/%i does not match disk length of %i sectors.  Exiting.", numberofside, numberoftrack, numberofsector, nbsector);
			return HXCFE_FILECORRUPTED;
		}


 
		imgldr_ctx->hxcfe->hxc_printf(MSG_INFO_1, "Disk geometry is %i sides, %i tracks per side, %i sectors per track.", numberofside, numberoftrack, numberofsector);

		imagesize = numberofsector * numberoftrack * numberofside * sectorsize;
		diskimage = malloc(imagesize);
		if (!diskimage)
			return HXCFE_INTERNALERROR;
		memset(diskimage, 0xF6, imagesize);

		for(i=0;i<numberofside;i++)
		{
			for(j=0;j<numberoftrack;j++)
			{
				hxcfe_imgCallProgressCallback(imgldr_ctx, j + (i*numberoftrack),numberofside*numberoftrack);

				for(k=0;k<numberofsector;k++)
				{
					sc = hxcfe_searchSector(ss,j,i,k,density);
					if(sc)
					{
						if(sc->use_alternate_data_crc)
							imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Warning : Bad Data CRC : T:%d H:%d S:%d Size :%dB",j,i,k,sc->sectorsize);

						if(sc->sectorsize == sectorsize)
						{
							if(i==0)
								file_offset=(j*numberofsector)*sectorsize + ( k * sectorsize );
							else
								file_offset=(  numberoftrack      *numberofsector*sectorsize) +
												(((numberoftrack-1)-j)*numberofsector*sectorsize) +
												( k * sectorsize );
							memcpy(&diskimage[file_offset], sc->input_data, sectorsize);
						} else {
							error++;
							imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Bad Sector Size : T:%d H:%d S:%d Size :%dB, Should be %dB",j,i,k,sc->sectorsize,sectorsize);
						}

						hxcfe_freeSectorConfig(ss,sc);
					} else {
						imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Sector not found : T:%d H:%d S:%d",j,i,k);
					}
				}
			}
		}

		if(!error)
		{
			ti99v9t9file=hxc_fopen(filename,"wb");
			if(ti99v9t9file)
			{
				fwrite(diskimage,imagesize,1,ti99v9t9file);
				hxc_fclose(ti99v9t9file);
			} else {
				free(diskimage);
				hxcfe_deinitSectorAccess(ss);
				return HXCFE_ACCESSERROR;
			}
		}
	}

	free(diskimage);
	hxcfe_deinitSectorAccess(ss);

	if(!error)
		return HXCFE_NOERROR;
	else
	{
		imgldr_ctx->hxcfe->hxc_printf(MSG_ERROR,"Errors were found in this disk image.");
		return HXCFE_FILECORRUPTED;
	}
}