|
|
|
@@ -28,6 +28,13 @@
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
|
|
|
|
|
|
#include "version.h"
|
|
|
|
|
|
|
|
|
|
#include "h17_format.h"
|
|
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
|
|
|
|
|
@@ -39,8 +46,250 @@
|
|
|
|
|
#include "tracks/sector_extractor.h"
|
|
|
|
|
#include "libhxcadaptor.h"
|
|
|
|
|
|
|
|
|
|
int write_meta_data_track(FILE * f,HXCFE_SECTORACCESS* ss,int32_t startidsector,int32_t sectorpertrack,int32_t trk,int32_t side,int32_t sectorsize,int32_t tracktype, int * badsect, int * missingsect )
|
|
|
|
|
{
|
|
|
|
|
int sect;
|
|
|
|
|
HXCFE_SECTCFG * scfg;
|
|
|
|
|
|
|
|
|
|
h17_sect_metadata sect_meta;
|
|
|
|
|
|
|
|
|
|
for( sect = 0 ; sect < sectorpertrack ; sect++ )
|
|
|
|
|
{
|
|
|
|
|
memset(§_meta,0,sizeof(sect_meta));
|
|
|
|
|
|
|
|
|
|
scfg = hxcfe_searchSector ( ss, trk, side, startidsector + sect, tracktype );
|
|
|
|
|
if( scfg )
|
|
|
|
|
{
|
|
|
|
|
if( scfg->use_alternate_data_crc || !scfg->input_data )
|
|
|
|
|
{
|
|
|
|
|
*badsect = *badsect + 1;
|
|
|
|
|
|
|
|
|
|
if(!scfg->input_data)
|
|
|
|
|
sect_meta.Sector_Status |= 0x10;
|
|
|
|
|
|
|
|
|
|
if(scfg->use_alternate_data_crc)
|
|
|
|
|
sect_meta.Sector_Status |= 0x20;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( scfg->cylinder != trk )
|
|
|
|
|
{
|
|
|
|
|
sect_meta.Sector_Status |= 0x02;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sect_meta.Track = scfg->cylinder;
|
|
|
|
|
sect_meta.Sector = scfg->sector;
|
|
|
|
|
sect_meta.Data_Checksum = scfg->data_crc;
|
|
|
|
|
sect_meta.Header_Checksum = scfg->header_crc;
|
|
|
|
|
sect_meta.DSync = scfg->alternate_datamark;
|
|
|
|
|
sect_meta.Volume = (scfg->alternate_addressmark>>8) & 0xFF;
|
|
|
|
|
sect_meta.HSync = scfg->alternate_addressmark & 0xFF;
|
|
|
|
|
sect_meta.Valid_Bytes = BIGENDIAN_WORD(256);
|
|
|
|
|
sect_meta.Offset = BIGENDIAN_DWORD( 256 + (((trk * sectorpertrack) + sect) * sectorsize) ) ;
|
|
|
|
|
|
|
|
|
|
hxcfe_freeSectorConfig( ss , scfg );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*missingsect = *missingsect + 1;
|
|
|
|
|
|
|
|
|
|
sect_meta.Track = trk;
|
|
|
|
|
sect_meta.Sector = sect;
|
|
|
|
|
sect_meta.Data_Checksum = 0x0000;
|
|
|
|
|
sect_meta.Header_Checksum = 0x0000;
|
|
|
|
|
sect_meta.DSync = 0x00;
|
|
|
|
|
sect_meta.Volume = 0x00;
|
|
|
|
|
sect_meta.HSync = 0x00;
|
|
|
|
|
sect_meta.Valid_Bytes = 0;
|
|
|
|
|
sect_meta.Offset = 0;
|
|
|
|
|
sect_meta.Sector_Status = 0x59;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fwrite(§_meta,sizeof(sect_meta),1,f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int write_meta_data(HXCFE_IMGLDR * imgldr_ctx,FILE * f,HXCFE_FLOPPY * fp,int32_t startidsector,int32_t sectorpertrack,int32_t nboftrack,int32_t nbofside,int32_t sectorsize,int32_t tracktype,int32_t sidefilelayout)
|
|
|
|
|
{
|
|
|
|
|
int trk,side;
|
|
|
|
|
HXCFE_SECTORACCESS* ss;
|
|
|
|
|
int badsect,missingsect;
|
|
|
|
|
|
|
|
|
|
badsect = 0;
|
|
|
|
|
missingsect = 0;
|
|
|
|
|
|
|
|
|
|
if(f && fp)
|
|
|
|
|
{
|
|
|
|
|
ss = hxcfe_initSectorAccess( imgldr_ctx->hxcfe, fp );
|
|
|
|
|
if(ss)
|
|
|
|
|
{
|
|
|
|
|
for( trk = 0 ; trk < nboftrack ; trk++ )
|
|
|
|
|
{
|
|
|
|
|
for( side = 0 ; side < nbofside; side++ )
|
|
|
|
|
{
|
|
|
|
|
write_meta_data_track(f,ss,startidsector,sectorpertrack,trk,side,sectorsize,tracktype,&badsect,&missingsect );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hxcfe_deinitSectorAccess(ss);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(badsect || missingsect)
|
|
|
|
|
return HXCFE_FILECORRUPTED;
|
|
|
|
|
else
|
|
|
|
|
return HXCFE_NOERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Main writer function
|
|
|
|
|
int H17_libWrite_DiskFile(HXCFE_IMGLDR* imgldr_ctx,HXCFE_FLOPPY * floppy,char * filename)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
int nbsector;
|
|
|
|
|
int nbtrack;
|
|
|
|
|
int nbside;
|
|
|
|
|
int sectorsize;
|
|
|
|
|
|
|
|
|
|
int writeret;
|
|
|
|
|
int offset;
|
|
|
|
|
int offset2;
|
|
|
|
|
|
|
|
|
|
FILE * h8dfile;
|
|
|
|
|
|
|
|
|
|
unsigned int sectorcnt_s0;
|
|
|
|
|
unsigned int sectorcnt_s1;
|
|
|
|
|
|
|
|
|
|
h17_block blk;
|
|
|
|
|
h17_DskF DskF;
|
|
|
|
|
h17_Parm Parm;
|
|
|
|
|
h17_header hdr;
|
|
|
|
|
|
|
|
|
|
struct tm * ts;
|
|
|
|
|
time_t currenttime;
|
|
|
|
|
|
|
|
|
|
char str_tmp[512];
|
|
|
|
|
|
|
|
|
|
sectorsize = 256;
|
|
|
|
|
|
|
|
|
|
hxcfe_imgCallProgressCallback(imgldr_ctx,0,floppy->floppyNumberOfTrack*2 );
|
|
|
|
|
|
|
|
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_INFO_1,"Write H17 Heathkit file %s...",filename);
|
|
|
|
|
|
|
|
|
|
sectorcnt_s0 = count_sector(imgldr_ctx->hxcfe,floppy,0,0,0,sectorsize,HEATHKIT_HS_FM_ENCODING,0x0000);
|
|
|
|
|
sectorcnt_s1 = count_sector(imgldr_ctx->hxcfe,floppy,0,0,1,sectorsize,HEATHKIT_HS_FM_ENCODING,0x0000);
|
|
|
|
|
|
|
|
|
|
writeret = HXCFE_ACCESSERROR;
|
|
|
|
|
|
|
|
|
|
h8dfile = hxc_fopen(filename,"wb");
|
|
|
|
|
if(h8dfile)
|
|
|
|
|
{
|
|
|
|
|
memcpy((void*)&hdr.file_tag,"H17D",4);
|
|
|
|
|
memcpy((void*)&hdr.version,"200",3);
|
|
|
|
|
hdr.check = 0xFF;
|
|
|
|
|
fwrite(&hdr,sizeof(hdr),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
if(sectorcnt_s0 != 10)
|
|
|
|
|
{
|
|
|
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_INFO_1,"Error : Disk format doesn't match...",filename);
|
|
|
|
|
return HXCFE_FILECORRUPTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nbtrack = 40;
|
|
|
|
|
while(nbtrack && !count_sector(imgldr_ctx->hxcfe,floppy,0,nbtrack-1,0,sectorsize,HEATHKIT_HS_FM_ENCODING,0x0000))
|
|
|
|
|
{
|
|
|
|
|
nbtrack--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nbside = 1;
|
|
|
|
|
if(sectorcnt_s1)
|
|
|
|
|
nbside = 2;
|
|
|
|
|
|
|
|
|
|
blk.id = BLKID_DskF;
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD(sizeof(DskF));
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
DskF.Tracks = nbtrack;
|
|
|
|
|
DskF.Sides = nbside;
|
|
|
|
|
DskF.ReadOnly = 0;
|
|
|
|
|
fwrite(&DskF,sizeof(DskF),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
blk.id = BLKID_Parm;
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD(sizeof(Parm));
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
Parm.Distribution_Disk = 0;
|
|
|
|
|
Parm.Source_of_Header_Data = 0;
|
|
|
|
|
fwrite(&Parm,sizeof(Parm),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
sprintf(str_tmp,"HxC Floppy Emulator software v%s\nhttps://hxc2001.com",STR_FILE_VERSION2);
|
|
|
|
|
blk.id = BLKID_Prog;
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD(strlen(str_tmp));
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
fwrite(&str_tmp,strlen(str_tmp),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
strcpy(str_tmp,"");
|
|
|
|
|
blk.id = BLKID_Imgr;
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD(strlen(str_tmp));
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
fwrite(&str_tmp,strlen(str_tmp),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
currenttime=time (NULL);
|
|
|
|
|
ts=localtime(¤ttime);
|
|
|
|
|
|
|
|
|
|
sprintf(str_tmp,"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d,000Z",ts->tm_year+1900,ts->tm_mon,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
|
|
|
|
|
blk.id = BLKID_Date;
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD(strlen(str_tmp));
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
fwrite(&str_tmp,strlen(str_tmp),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
offset = ftell(h8dfile);
|
|
|
|
|
|
|
|
|
|
if( (offset + sizeof(blk)) & 0xFF )
|
|
|
|
|
{
|
|
|
|
|
blk.id = BLKID_Padd;
|
|
|
|
|
offset += sizeof(blk);
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD( (0x100 - ((offset + sizeof(blk)) & 0xFF)) & 0xFF );
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
memset(str_tmp,0,sizeof(str_tmp));
|
|
|
|
|
fwrite(&str_tmp,BIGENDIAN_DWORD(blk.lenght),1,h8dfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
blk.id = BLKID_H8DB;
|
|
|
|
|
blk.lenght = 0;
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
offset = ftell(h8dfile);
|
|
|
|
|
|
|
|
|
|
nbsector = sectorcnt_s0;
|
|
|
|
|
|
|
|
|
|
imgldr_ctx->hxcfe->hxc_printf(MSG_INFO_1,"%d sectors (%d bytes), %d tracks, %d sides...",nbsector,sectorsize,nbtrack,nbside);
|
|
|
|
|
|
|
|
|
|
writeret = write_raw_file(imgldr_ctx,h8dfile,floppy,0,nbsector,nbtrack,nbside,sectorsize,HEATHKIT_HS_FM_ENCODING,1);
|
|
|
|
|
|
|
|
|
|
offset2 = ftell(h8dfile);
|
|
|
|
|
// update size
|
|
|
|
|
fseek(h8dfile,offset - sizeof(blk),SEEK_SET);
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD( offset2 - offset );
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
fseek(h8dfile,0,SEEK_END);
|
|
|
|
|
|
|
|
|
|
blk.id = BLKID_SecM;
|
|
|
|
|
blk.lenght = 0;
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
|
|
|
|
|
offset = ftell(h8dfile);
|
|
|
|
|
|
|
|
|
|
writeret = write_meta_data(imgldr_ctx,h8dfile,floppy,0,nbsector,nbtrack,nbside,sectorsize,HEATHKIT_HS_FM_ENCODING,1);
|
|
|
|
|
|
|
|
|
|
offset2 = ftell(h8dfile);
|
|
|
|
|
|
|
|
|
|
// update size
|
|
|
|
|
fseek(h8dfile,offset - sizeof(blk),SEEK_SET);
|
|
|
|
|
blk.lenght = BIGENDIAN_DWORD( offset2 - offset );
|
|
|
|
|
fwrite(&blk,sizeof(blk),1,h8dfile);
|
|
|
|
|
fseek(h8dfile,0,SEEK_END);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hxc_fclose(h8dfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return writeret;
|
|
|
|
|
}
|
|
|
|
|