中国DOS联盟论坛

中国DOS联盟
-- 联合DOS 推动DOS 发展DOS --

联盟域名:cndos.rths.ml  论坛域名:cndos.rths.ml/forum

DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

» 游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助

 

<<   [1] [2]  >>   >
作者:
标题: 写了个HD-COPY IMG转普通IMA格式软盘镜像的软件 上一主题 | 下一主题
rgwan
初级用户





积分 22
发帖 8
注册 2018-3-19
状态 离线
『楼 主』:  写了个HD-COPY IMG转普通IMA格式软盘镜像的软件

废话少说,放源码!

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

编译好的程序下载:

http://rthost.fam.cx/cndos-up/img/2357.zip

另外求UCDOS3.1版的扩充字库!感激不尽!打算做一些压缩和优化,使得它们继续发挥余热!

[ Last edited by rgwan on 2018-3-20 at 00:23 ]

   此帖被 +2 点积分    点击查看详情   
评分人:【&sid=qfv0ZO zzz19760225 分数: +2  时间:2018-3-20 22:36


2018-3-20 00:22
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
LoggerVick
中级用户




积分 326
发帖 189
注册 2018-1-27
状态 离线
『第 2 楼』:  

不过可能你的附件会很少有人下载,我先顶一下。



动画城MV(我录制的欧洲版的,720P喔!)
2018-3-20 00:31
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
LoggerVick
中级用户




积分 326
发帖 189
注册 2018-1-27
状态 离线
『第 3 楼』:  



  Quote:
Originally posted by rgwan at 2018-3-20 00:22:
废话少说,放源码!

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

编译好的程序下载:

http://rthost.fam.cx/cndos-up/img/2357.zip

另外求UCDOS3.1版的扩 ...

我已经向我加的联盟群询问字库了,有的话应该会提示你去那个群下载。

[ Last edited by LoggerVick on 2018-3-20 at 00:46 ]



动画城MV(我录制的欧洲版的,720P喔!)
2018-3-20 00:36
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
rgwan
初级用户





积分 22
发帖 8
注册 2018-3-19
状态 离线
『第 4 楼』:  

http://cndos.fam.cx/forum/viewth ... =%E6%B1%87%E9%BE%99

已经找到啦,感谢mys先生!

2018-3-20 08:46
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 5 楼』:  

程序不错,英文语句稍有点不统一,前面是decompress,后面是Decode,两者有点区别的。
另外提个小建议,这种DOS程序最好使用TC或者BC,DOS文本格式,GCC对很多初入门者有点复杂。C99标准比较晚,而程序中只用了stdint.h中的数据类型,如果改成老标准C89更方便大家学习。



从来不用别人的东西,要用,也先改成自己的再说!
2018-3-20 12:19
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 6 楼』:  

刚转换到TC2.0,编译后DOS下测试发现严重问题,看来对hd-copy的img格式分析还不全面。确认为hd-copy 2.0a的img居然解压不出,只写出个32k的头。再测试gcc编译版本,完全不支持DOS,cmd下可以运行,但是解压img却出错退出。



从来不用别人的东西,要用,也先改成自己的再说!
2018-3-20 13:25
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 7 楼』:  

既然源码是牛X的WTFPL开源协议,我就乱改了
DOS版源码请看后面第14楼层,下载地址在15楼。





[ Last edited by crshen on 2018-3-21 at 16:24 ]



从来不用别人的东西,要用,也先改成自己的再说!
2018-3-20 13:38
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
rgwan
初级用户





积分 22
发帖 8
注册 2018-3-19
状态 离线
『第 8 楼』:  

能否将出错的Image发给我?另外的,这个程序其实并不运行在DOS环境下。设计上是配合Windows/Linux,给虚拟机使用的。

此外,我做了一些修复,不知对于您的Image是否奏效。
CODE:  [Copy to clipboard]
#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> [size]\n\n", argv[0]);
                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[3]);
        }
        fp = fopen(argv[1], "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[0] == 0xff && hdcopy[1] == 0x18)
        {
                printf("That is an HD-COPY 2.0 Image\n");
                actualimage = hdcopy + 0x0e; /* 跳过标有卷标的文件头 */
                payload = actualimage + 2 + 168; /* 载荷段 */
        }
        else
        {
                printf("That is an HD-COPY 1.7 Image\n");
                actualimage = hdcopy;
                payload = actualimage + 2 + 164;
        }
        /* 开始解码 */
        int maxTrackCount = actualimage[0];
        int secPerTrack = actualimage[1];

        printf("maxTrackCount = %d, secPerTrack = %d\n", maxTrackCount, secPerTrack);
        uint8_t *dataTrack = actualimage + 2; /* 有数据的磁道表 */

        uint8_t *decomp_p = plain;

        memset(plain, 0x00, 0x168000);

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

                                                for(r = 0; r < repeat; r++)
                                                {
                                                        *(decomp_p++) = repeatByte;
                                                }
                                        }
                                        else
                                        {
                                                *(decomp_p++) = payload[k];
                                        }
                                }
                        }
                        payload += dataLen;
                }
        }
        uint16_t secCount = plain[0x13] + (plain[0x14] << 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[2], "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 ]

2018-3-20 18:59
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
LoggerVick
中级用户




积分 326
发帖 189
注册 2018-1-27
状态 离线
『第 9 楼』:  



  Quote:
Originally posted by rgwan at 2018-3-20 18:59:
能否将出错的Image发给我?另外的,这个程序其实并不运行在DOS环境下。设计上是配合Windows/Linux,给虚拟机使用的。

此外,我做了一些修复,不知对 ...

他qq不加好友,你加入群可以搜索一下crshen然后他看到就能给你。



动画城MV(我录制的欧洲版的,720P喔!)
2018-3-20 22:11
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
LoggerVick
中级用户




积分 326
发帖 189
注册 2018-1-27
状态 离线
『第 10 楼』:  

或者试试新dos时代纪念光盘crshen留的email



动画城MV(我录制的欧洲版的,720P喔!)
2018-3-20 22:38
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
LoggerVick
中级用户




积分 326
发帖 189
注册 2018-1-27
状态 离线
『第 11 楼』:  

crshen:@[论坛]Willard 知道,我今天单位夜班,没法回他,一晚不睡,明天要睡一天,估计明下午4点后回复他吧。



动画城MV(我录制的欧洲版的,720P喔!)
2018-3-20 23:06
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 12 楼』:  

回复rgwan:
经测试,程序已基本能解压HD-copy的img,但是源码中存在些瑕疵:
1、i 的 for 循环明显错误,查看img格式文档,byte    tracks; // total tracks - 1,这里是以0起计数的,80道显示为79,故要改for (i = 0; i <= maxTrackCount; i++),否则在一些比较满的磁盘会缺一个磁道数据。
2、对 for(k = 0; k < dataLen; k++) 中k==0的判断,几乎每个磁道将进行上万次,影响效率,可改:
escByte = payload[0];
            for (k = 1; k < dataLen; k++){}



从来不用别人的东西,要用,也先改成自己的再说!
2018-3-21 15:36
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 13 楼』:  

软件测试环境:
1、Ubuntu 16.04 ,gcc编译,命令行下运行正常;
2、Win7 x64 + CodeBlocks 17.12 mingw,cmd环境运行正常;
3、XP + cfree5.0默认gcc3.45,cmd环境运行正常;
4、DOS 6.22 + Turbo C 2.0,运行正常,拷贝到win98,command下运行正常。

测试方法:
1、磁盘映像,选用mys的起步DOS网站下10个HD-COPY img,包括1.44M和1.2M;
2、单命令行执行;
3、批处理执行:for %i in (dir *.img) do dehd.exe %i dest\%i (将当前目录下所有HD-COPY格式img 转换到 标准格式img,保存至dest目录下同名文件)。



从来不用别人的东西,要用,也先改成自己的再说!
2018-3-21 15:44
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 14 楼』:  

首先感谢rgwan分享源码,这里是我修改的DOS版本,可用TC2.0或BC3.1编译。

由于DOS内存限制,不可能像保护模式下那样直接申请一个大内存,故数据解码需频繁进行文件读写,磁盘IO速度自然比不上内存,效率较CMD版要差些。
CODE:  [Copy to clipboard]
#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[0]);
        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[1], "rb");
    if (!fpin)
    {
        fprintf(stderr, "Can't open source HD-COPY image!\n");
        exit(-1);
    }

    fpout = fopen(argv[2], "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[0] == 0xff && buffer[1] == 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[0];   /* total tracks - 1 */
    nSecPerTrack = buffer[1];
    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); /* 一个标准磁道容量 */
    hdcopy = 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[(i * 2) + j] != 0x01) /* 映射为空磁道 */
            {
                memset(plain, 0x00, nBytesPerTrack);
                fwrite(plain, nBytesPerTrack, 1, fpout);
                continue;
            }
            fseek(fpin, nFinPos, SEEK_SET);
            fread(buffer, 2, 1, fpin);
            nDataLen = buffer[0] + (buffer[1] << 8); /* little endian */
            memset(hdcopy, 0x00, nBytesPerTrack);
            fread(hdcopy, nDataLen, 1, fpin);
            nFinPos = nFinPos + 2 + nDataLen;
            escByte = hdcopy[0];
            for (k = 1; k < nDataLen; k++)  /* RLE压缩的磁道内容解压 */
            {
                if (hdcopy[k] == escByte)
                {
                    k++;
                    repeatByte = hdcopy[k++];
                    repeat = hdcopy[k];
                    for (r = 0; r < repeat; r++)
                    {
                        *(plain++) = repeatByte;
                    }
                }
                else
                {
                    *(plain++) = hdcopy[k];
                }
            }
            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 ]



从来不用别人的东西,要用,也先改成自己的再说!
2018-3-21 15:51
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
crshen
中级用户




积分 444
发帖 125
注册 2004-2-10
状态 离线
『第 15 楼』:  

源码文件和已经预编译的程序可到百度网盘下载:
DOS软件共享\解压HD-COPY映像到标准img.rar

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


或者加 QQ群:中華DOS聯盟(8393170),到群文件中下载。

[ Last edited by crshen on 2018-3-21 at 16:25 ]

   此帖被 +7 点积分     点击查看详情   
评分人:【&sid=qfv0ZO zzz19760225 分数: +5  时间:2018-3-21 22:01
评分人:【&sid=qfv0ZO LoggerVick 分数: +2  时间:2018-3-21 22:50




从来不用别人的东西,要用,也先改成自己的再说!
2018-3-21 16:08
查看资料  发送邮件  发短消息 网志  QQ   编辑帖子  回复  引用回复
<<   [1] [2]  >>   >
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转:  



[ 联系我们 - 中国DOS联盟 ]


Powered by Discuz! © 2001-2011