'The rewritten codes uses dehd-cmd.exe originall codes,
'in addition, one minor error skipped off when continue
'occurs at the final track by JUST close the files and
'return 0 to force the program to END for Completion.
'
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv)
{
    FILE *fpin, *fpout;
	unsigned int nBytesPerTrack;
	unsigned char repeatByte;
    unsigned char *buffer, *hdcopy, *plain, *pnDataTrkMap;
    unsigned long nTrackCount, nSecPerTrack, nActualImgAddr, nImgDataAddr, escByte, repeat;
    unsigned long nDataLen;
    unsigned long nFinPos;
    unsigned long i, j, k, r;
    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s <HD-COPY Image> <IMA plain floppy image>\n\n", argv);
        fprintf(stderr, "This small tool decompress HD-COPY image to plain floppy image.\n");
        fprintf(stderr, "Therefore, you can use old HD-COPY img on modern PC or Virtual Machine.\n\n");
        fprintf(stderr, "Zhiyuan Wan <
h@iloli.bid> 2018, License WTFPL.\nAlgorithm analyze from <
https://github.com/ciel-yu/devnotes>. Thanks him!\n");
        fprintf(stderr, "Modified to suit old DOS by crshen <
crshen@qq.com>.\n\n");
        exit(-1);
    }
    
	fpin = fopen(argv, "rb");
    if (!fpin)
    {
        fprintf(stderr, "Can't open source HD-COPY image!\n");
        exit(-1);
    }
    fpout = fopen(argv, "wb+");
    if (!fpout)
    {
        fprintf(stderr, "Can't save plain floppy image!\n");
        exit(-1);
    }
    buffer = (unsigned char *)malloc(2);
    fseek(fpin, 0, SEEK_SET);
    fread(buffer, 2, 1, fpin);
    if (buffer == 0xff && buffer == 0x18)
    {
        printf("Source img is an HD-COPY 2.0 Image\n");
        nActualImgAddr = 14; /* 跳过标有卷标的文件头 */
        nImgDataAddr = nActualImgAddr + 2 + 168; /* 磁道数据起始 */
    }
    else
    {
        printf("Source img may be an HD-COPY 1.7 Image\n");
        nActualImgAddr = 0;
        nImgDataAddr = nActualImgAddr + 2 + 164;
    }
    fseek(fpin, nActualImgAddr, SEEK_SET);
    fread(buffer, 2, 1, fpin);
    nTrackCount = buffer;   /* total tracks - 1 */
    nSecPerTrack = buffer;
    nBytesPerTrack = 512 * nSecPerTrack;
    printf("nTrackCount = %d, nSecPerTrack = %d\n", nTrackCount, nSecPerTrack);
    pnDataTrkMap = (unsigned char *)malloc(2 * (nTrackCount + 1));
    fseek(fpin, nActualImgAddr + 2, SEEK_SET);  /* tracks_map */
    fread(pnDataTrkMap, 2 * (nTrackCount + 1), 1, fpin);
    plain = (unsigned char *)malloc(nBytesPerTrack); /* 一个标准磁道容量 */
    hdcopy = (unsigned char *)malloc(nBytesPerTrack); /* 存放压缩磁道数据 */
    nFinPos = nImgDataAddr;
    printf("Working hard,please wait...\n");
    fseek(fpout, 0, SEEK_SET);
			for (i = 0; i <= nTrackCount; i++)
			{
				for (j = 0; j < 2; j++)
				{
					if (pnDataTrkMap != 0x01) /* 映射为空磁道 */
					{
						memset(plain, 0x00, nBytesPerTrack);
						fwrite(plain, nBytesPerTrack, 1, fpout);
						if (i==nTrackCount) 
							{
								fclose(fpin);
								fclose(fpout);
								return 0;
							} 
						else{   continue;}
					}
					
					fseek(fpin, nFinPos, SEEK_SET);
					fread(buffer, 2, 1, fpin);
					nDataLen = buffer + (buffer << 8); /* little endian */
					memset(hdcopy, 0x00, nBytesPerTrack);
					fread(hdcopy, nDataLen, 1, fpin);
					nFinPos = nFinPos + 2 + nDataLen;
					escByte = hdcopy;
					for (k = 1; k < nDataLen; k++)  /* RLE压缩的磁道内容解压 */
					{
						if (hdcopy == escByte)
						{
							k++;
							repeatByte = hdcopy;
							repeat = hdcopy;
							for (r = 0; r < repeat; r++)
							{
								*(plain++) = repeatByte;
							}
						}
						else
						{
							*(plain++) = hdcopy;
						}
					}
					plain -= nBytesPerTrack;
					fwrite(plain, nBytesPerTrack, 1, fpout);            
				}
			}
    fclose(fpin);
    fclose(fpout);
    free(hdcopy);
    free(buffer);
    free(pnDataTrkMap);
    free(plain);
    printf("Decompress operation completed.\n");
    return 0;
}
 
重写的代码使用了dehd - cmd.exe的原始代码,此外,当在最后一个磁道继续时出现的一个小错误通过简单关闭文件并返回0来强制程序结束以完成操作。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv)
{
    FILE *fpin, *fpout;
    unsigned int nBytesPerTrack;
    unsigned char repeatByte;
    unsigned char *buffer, *hdcopy, *plain, *pnDataTrkMap;
    unsigned long nTrackCount, nSecPerTrack, nActualImgAddr, nImgDataAddr, escByte, repeat;
    unsigned long nDataLen;
    unsigned long nFinPos;
    unsigned long i, j, k, r;
    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s <HD-COPY Image> <IMA plain floppy image>\n\n", argv);
        fprintf(stderr, "This small tool decompress HD-COPY image to plain floppy image.\n");
        fprintf(stderr, "Therefore, you can use old HD-COPY img on modern PC or Virtual Machine.\n\n");
        fprintf(stderr, "Zhiyuan Wan <
h@iloli.bid> 2018, License WTFPL.\nAlgorithm analyze from <
https://github.com/ciel-yu/devnotes>. Thanks him!\n");
        fprintf(stderr, "Modified to suit old DOS by crshen <
crshen@qq.com>.\n\n");
        exit(-1);
    }
    fpin = fopen(argv, "rb");
    if (!fpin)
    {
        fprintf(stderr, "Can't open source HD-COPY image!\n");
        exit(-1);
    }
    fpout = fopen(argv, "wb+");
    if (!fpout)
    {
        fprintf(stderr, "Can't save plain floppy image!\n");
        exit(-1);
    }
    buffer = (unsigned char *)malloc(2);
    fseek(fpin, 0, SEEK_SET);
    fread(buffer, 2, 1, fpin);
    if (buffer == 0xff && buffer == 0x18)
    {
        printf("Source img is an HD-COPY 2.0 Image\n");
        nActualImgAddr = 14; /* Skip the file header marked with the volume label */
        nImgDataAddr = nActualImgAddr + 2 + 168; /* Start of track data */
    }
    else
    {
        printf("Source img may be an HD-COPY 1.7 Image\n");
        nActualImgAddr = 0;
        nImgDataAddr = nActualImgAddr + 2 + 164;
    }
    fseek(fpin, nActualImgAddr, SEEK_SET);
    fread(buffer, 2, 1, fpin);
    nTrackCount = buffer;   /* total tracks - 1 */
    nSecPerTrack = buffer;
    nBytesPerTrack = 512 * nSecPerTrack;
    printf("nTrackCount = %d, nSecPerTrack = %d\n", nTrackCount, nSecPerTrack);
    pnDataTrkMap = (unsigned char *)malloc(2 * (nTrackCount + 1));
    fseek(fpin, nActualImgAddr + 2, SEEK_SET);  /* tracks_map */
    fread(pnDataTrkMap, 2 * (nTrackCount + 1), 1, fpin);
    plain = (unsigned char *)malloc(nBytesPerTrack); /* A standard track capacity */
    hdcopy = (unsigned char *)malloc(nBytesPerTrack); /* Store compressed track data */
    nFinPos = nImgDataAddr;
    printf("Working hard,please wait...\n");
    fseek(fpout, 0, SEEK_SET);
    for (i = 0; i <= nTrackCount; i++)
    {
        for (j = 0; j < 2; j++)
        {
            if (pnDataTrkMap != 0x01) /* The map is an empty track */
            {
                memset(plain, 0x00, nBytesPerTrack);
                fwrite(plain, nBytesPerTrack, 1, fpout);
                if (i == nTrackCount)
                {
                    fclose(fpin);
                    fclose(fpout);
                    return 0;
                }
                else
                {
                    continue;
                }
            }
            fseek(fpin, nFinPos, SEEK_SET);
            fread(buffer, 2, 1, fpin);
            nDataLen = buffer + (buffer << 8); /* little endian */
            memset(hdcopy, 0x00, nBytesPerTrack);
            fread(hdcopy, nDataLen, 1, fpin);
            nFinPos = nFinPos + 2 + nDataLen;
            escByte = hdcopy;
            for (k = 1; k < nDataLen; k++)  /* Decompress the track content of RLE compression */
            {
                if (hdcopy == escByte)
                {
                    k++;
                    repeatByte = hdcopy;
                    repeat = hdcopy;
                    for (r = 0; r < repeat; r++)
                    {
                        *(plain++) = repeatByte;
                    }
                }
                else
                {
                    *(plain++) = hdcopy;
                }
            }
            plain -= nBytesPerTrack;
            fwrite(plain, nBytesPerTrack, 1, fpout);
        }
    }
    fclose(fpin);
    fclose(fpout);
    free(hdcopy);
    free(buffer);
    free(pnDataTrkMap);
    free(plain);
    printf("Decompress operation completed.\n");
    return 0;
}