China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --

Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
DOS stands for freedom, openness and progress. Let us work hard, learn from the openness and GNU spirit of FreeDOS and Linux, and together build and grow a free GNU GPL world!

中国DOS联盟论坛
The time now is 2026-06-20 12:58
中国DOS联盟论坛 » DOS软件下载 & 游戏分享 (下载室) » Wrote a software for converting HD-COPY IMG to ordinary IMA format floppy disk images View 8,253 Replies 22
Original Poster Posted 2018-03-20 00:22 ·  中国 四川 移动
初级用户
Credits 22
Posts 8
Joined 2018-03-19 00:55
8-year member
UID 182714
Gender Male
Status Offline
Cut the chatter, post the source code!

https://github.com/rgwan/hdcopy-tools

Compiled program download:

http://upload.cn-dos.net/img/2357.zip

Also, looking for the extended font of UCDOS 3.1! Greatly appreciated! Planning to do some compression and optimization so that they can continue to be useful!

[ Last edited by rgwan on 2018-3-20 at 00:23 ]
Recent Ratings for This Post ( 1 in total) Click for details
RaterScoreTime
zzz19760225 +2 2018-03-20 22:36
Floor 2 Posted 2018-03-20 00:31 ·  中国 黑龙江 移动
中级用户
★★
Credits 365
Posts 212
Joined 2018-01-27 00:00
8-year member
UID 182622
Status Offline
But maybe few people will download your attachment. I'll give it a bump first.
很少上线的游客前来。
Floor 3 Posted 2018-03-20 00:36 ·  中国 黑龙江 移动
中级用户
★★
Credits 365
Posts 212
Joined 2018-01-27 00:00
8-year member
UID 182622
Status Offline
Originally posted by rgwan at 2018-3-20 00:22:
Cut the chatter, post the source code!

https://github.com/rgwan/hdcopy-tools

Download compiled programs:

http://upload.cn-dos.net/img/2357.zip

Also seeking UCDOS 3.1 version expansion ...

I have inquired about the font in the alliance group I joined. If available, I should prompt you to download from that group.

[ Last edited by LoggerVick on 2018-3-20 at 00:46 ]
很少上线的游客前来。
Floor 4 Posted 2018-03-20 08:46 ·  中国 四川 成都 移动
初级用户
Credits 22
Posts 8
Joined 2018-03-19 00:55
8-year member
UID 182714
Gender Male
Status Offline
Floor 5 Posted 2018-03-20 12:19 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
The program is good, but the English sentences are a bit inconsistent. Earlier it's decompress, later it's Decode, there's a bit of a difference between the two. Also, I have a small suggestion. For such DOS programs, it's best to use TC or BC, in DOS text format. GCC is a bit complicated for many beginners. The C99 standard is relatively late, and the program only uses the data types in stdint.h. If it's changed to the older standard C89, it's more convenient for everyone to learn.
从来不用别人的东西,要用,也先改成自己的再说!
Floor 6 Posted 2018-03-20 13:25 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
Just switched to TC2.0, and serious problems were found during testing under DOS after compilation. It seems that the analysis of the img format of hd-copy is not comprehensive. The img confirmed to be of hd-copy 2.0a cannot be extracted, only a 32k header is written. Then tested the gcc-compiled version, which is completely incompatible with DOS, can run under cmd, but exits with an error when extracting the img.
从来不用别人的东西,要用,也先改成自己的再说!
Floor 7 Posted 2018-03-20 13:38 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
Since the source code is under the awesome WTFPL open source license, I just modified it randomly.

The DOS version source code can be seen in the 14th floor below, and the download address is on the 15th floor.



[ Last edited by crshen on 2018-3-21 at 16:24 ]
从来不用别人的东西,要用,也先改成自己的再说!
Floor 8 Posted 2018-03-20 18:59 ·  中国 四川 移动
初级用户
Credits 22
Posts 8
Joined 2018-03-19 00:55
8-year member
UID 182714
Gender Male
Status Offline
Can you send me the faulty Image? Additionally, this program doesn't actually run in a DOS environment. It's designed to work with Windows/Linux and for use in virtual machines.

Also, I made some fixes, not sure if they work for your Image.



#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

int main(int argc, char *argv)
{
FILE *fp;
uint8_t *hdcopy;
uint8_t *plain;
uint32_t length;
uint32_t fit_size = 0;

int i, j, k, r;

if(argc != 3 && argc != 4)
{
fprintf(stderr, "Usage: %s <HD-COPY Image> <IMA plain floppy image> \n\n", argv);
fprintf(stderr, "This small tool can decompress HD-COPY image to plain floppy image.\n");
fprintf(stderr, "It can help you to use old HD-COPY image on modern PC,\nespecially on Virtual Machine to test out old-school softwares.\n\n");
fprintf(stderr, "Zhiyuan Wan <h@iloli.bid> 2018, License WTFPL.\nAlgorithm analyze from <https://github.com/ciel-yu/devnotes>. Thanks him!\n");
exit(-1);
}
if(argc == 4)
{
fit_size = atoi(argv);
}
fp = fopen(argv, "rb");
if(!fp)
{
fprintf(stderr, "Can't open source HD-COPY image!\n");
exit(-1);
}
fseek(fp, 0, SEEK_END);
length = ftell(fp);

hdcopy = malloc(length);
plain = malloc(0x168000);

fseek(fp, 0, SEEK_SET);

fread(hdcopy, length, 1, fp);

printf("Decompressing HD-COPY Image\nInput size = %d\n", length);
fclose(fp);

uint8_t *actualimage;

uint8_t *payload;

if(hdcopy == 0xff && hdcopy == 0x18)
{
printf("That is an HD-COPY 2.0 Image\n");
actualimage = hdcopy + 0x0e; /* Skip the file header with volume label */
payload = actualimage + 2 + 168; /* Payload segment */
}
else
{
printf("That is an HD-COPY 1.7 Image\n");
actualimage = hdcopy;
payload = actualimage + 2 + 164;
}
/* Start decoding */
int maxTrackCount = actualimage;
int secPerTrack = actualimage;

printf("maxTrackCount = %d, secPerTrack = %d\n", maxTrackCount, secPerTrack);
uint8_t *dataTrack = actualimage + 2; /* Track table with data */

uint8_t *decomp_p = plain;

memset(plain, 0x00, 0x168000);

for(i = 0; i < maxTrackCount; i++)
{
for(j = 0; j < 2; j++)
{
if(dataTrack != 0x01)
{
decomp_p += 512 * secPerTrack;
continue;
}
int dataLen = payload + (payload << 8);
payload += 2;
uint8_t escByte; /* RLE compression */
for(k = 0; k < dataLen; k++)
{
if(k == 0)
{
escByte = payload;
}
else
{
if(payload == escByte)
{
k++;
uint8_t repeatByte = payload;
int repeat = payload;

for(r = 0; r < repeat; r++)
{
*(decomp_p++) = repeatByte;
}
}
else
{
*(decomp_p++) = payload;
}
}
}
payload += dataLen;
}
}
uint16_t secCount = plain + (plain << 8);
printf("Floppy sector count = %d, fitting to %d bytes\n",
secCount, fit_size > 0 ? fit_size : secCount * 512);
printf("Decompress operation completed, write it to file\n");
fp = fopen(argv, "wb+");
if(!fp)
{
fprintf(stderr, "Can't save plain floppy image!\n");
goto deal;
}
fseek(fp, 0, SEEK_SET);
fwrite(plain, fit_size > 0 ? fit_size : (secCount * 512 > 0 ? secCount * 512 : 0x168000), 1, fp);
fclose(fp);

deal:
free(hdcopy);
free(plain);
return 0;
}



[ Last edited by rgwan on 2018-3-20 at 19:01 ]
Floor 9 Posted 2018-03-20 22:11 ·  中国 黑龙江 移动
中级用户
★★
Credits 365
Posts 212
Joined 2018-01-27 00:00
8-year member
UID 182622
Status Offline
Originally posted by rgwan at 2018-3-20 18:59:
Can you send me the faulty Image? Additionally, this program does not actually run in a DOS environment. It is designed to work with Windows/Linux for use with virtual machines.

Furthermore, I have made some fixes, not sure about ...

He doesn't add QQ friends, you can join the group and search for crshen then he will see and can send it to you.
很少上线的游客前来。
Floor 10 Posted 2018-03-20 22:38 ·  中国 黑龙江 移动
中级用户
★★
Credits 365
Posts 212
Joined 2018-01-27 00:00
8-year member
UID 182622
Status Offline
Or try the new DOS era commemorative CD, the email left by crshen
很少上线的游客前来。
Floor 11 Posted 2018-03-20 23:06 ·  中国 黑龙江 移动
中级用户
★★
Credits 365
Posts 212
Joined 2018-01-27 00:00
8-year member
UID 182622
Status Offline
crshen:@[Forum]Willard knows that I'm on night shift at work today and can't reply to him. I won't sleep all night, and I'll need to sleep the whole day tomorrow. I estimate I'll reply to him after 4 PM tomorrow.
很少上线的游客前来。
Floor 12 Posted 2018-03-21 15:36 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
Reply to rgwan:
After testing, the program can basically decompress the img of HD - copy, but there are some flaws in the source code:
1. The for loop of i is obviously wrong. Looking at the img format document, byte tracks; // total tracks - 1, here it is counted from 0, 80 tracks are displayed as 79, so it is necessary to change for (i = 0; i <= maxTrackCount; i++) to otherwise, some relatively full disks will lack one track of data.
2. For the judgment of k == 0 in for (k = 0; k < dataLen; k++), it will be carried out tens of thousands of times for almost each track, which affects the efficiency. It can be changed to:
escByte = payload[0];
for (k = 1; k < dataLen; k++){}
从来不用别人的东西,要用,也先改成自己的再说!
Floor 13 Posted 2018-03-21 15:44 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
Software testing environment:
1. Ubuntu 16.04, compiled with gcc, runs normally in the command line;
2. Win7 x64 + CodeBlocks 17.12 mingw, runs normally in the cmd environment;
3. XP + cfree5.0 default gcc3.45, runs normally in the cmd environment;
4. DOS 6.22 + Turbo C 2.0, runs normally, copied to win98, runs normally under command.

Testing methods:
1. Disk image, select 10 HD-COPY img from the starting DOS website of mys, including 1.44M and 1.2M;
2. Execute with a single command line;
3. Execute with a batch script: for %i in (dir *.img) do dehd.exe %i dest\%i (convert all HD-COPY format img in the current directory to standard format img, and save to the same name file in the dest directory).
从来不用别人的东西,要用,也先改成自己的再说!
Floor 14 Posted 2018-03-21 15:51 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
First, thank rgwan for sharing the source code. Here is the DOS version I modified, which can be compiled with TC2.0 or BC3.1.

Due to the memory limitations of DOS, it's impossible to directly apply for a large amount of memory like in protected mode. Therefore, data decoding needs to frequently perform file reads and writes. The disk IO speed is naturally not as fast as memory, and the efficiency is worse than the CMD version.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv)
{
FILE *fpin, *fpout;
unsigned char *buffer, *hdcopy, *plain, *pnDataTrkMap;
int nTrackCount, nSecPerTrack, nBytesPerTrack, nActualImgAddr, nImgDataAddr, escByte, repeatByte, repeat;
unsigned int nDataLen;
unsigned long nFinPos;
int 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 = 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 = malloc(2 * (nTrackCount + 1));
fseek(fpin, nActualImgAddr + 2, SEEK_SET); /* tracks_map */
fread(pnDataTrkMap, 2 * (nTrackCount + 1), 1, fpin);

plain = malloc(nBytesPerTrack); /* Capacity of a standard track */
hdcopy = 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 mapping is an empty track */
{
memset(plain, 0x00, nBytesPerTrack);
fwrite(plain, nBytesPerTrack, 1, fpout);
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 compressed by 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;
}


[ Last edited by crshen on 2018-3-21 at 16:27 ]
从来不用别人的东西,要用,也先改成自己的再说!
Floor 15 Posted 2018-03-21 16:08 ·  中国 浙江 台州 移动
中级用户
★★
Credits 447
Posts 126
Joined 2004-02-10 00:00
22-year member
UID 17150
Gender Male
Status Offline
The source code files and pre-compiled programs can be downloaded from Baidu Netdisk:
DOS Software Sharing\Extract HD-COPY image to standard img.rar

pan.baidu.com/s/1toVeHvm1PHUL1d-dstROmA
Password: b5n5


Or join the QQ group: Zhonghua DOS Union (8393170) and download from the group files.

[ Last edited by crshen on 2018-3-21 at 16:25 ]
Recent Ratings for This Post ( 3 in total) Click for details
RaterScoreTime
zzz19760225 +5 2018-03-21 22:01
LoggerVick +2 2018-03-21 22:50
mongnewer +1 2023-09-23 09:59
从来不用别人的东西,要用,也先改成自己的再说!
Forum Jump: