⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hexbin.h

📁 一款国产的8051模拟器(全部源代码) 本软件是一款8051模拟器
💻 H
字号:
///////////////////////////////////////////////////////////////////////
// 圆梦51!圆梦51!圆梦51!圆梦51!圆梦51!圆梦51!圆梦51!圆梦51!圆梦51!圆梦51!
// 1998.x.x 多少遗憾,多少泪水,路在何方?? 为什么失败的总是我??梦想为什么这么遥远
// ........学x86很久了,书本都翻了n遍了......
// 虽然x86很强大,但要做台x86计算机真是太难了,8051单片机真的简单了很多,我想做个8051的计算机.
// 没有编程器的日子,真是不好受,自己又没条件能做电路板,要是能有台计算机模拟8051,那将是多莫令人兴奋的事情啊
// 但是我什么都没有............什么都没有
// 1999.x.x草稿纸上完成基本的框架图和基本算法,并完成部分核心代码,并将项目名称定为圆梦51
// .......飘啊摇啊,淡漠了生活,忘记了梦想,就这样浑浑噩噩的活着........梦已死
// 2002.8.24 尘世间多少烦恼,从此不必再牵挂。为了梦想我终于可以从现实中解脱出来一段时间,不上学的日子真好,真令人怀念。
// 建立指令模拟代码档。
// 不懂windows C编程是我最大的障碍,......1年时间......我想应该是我这一生中最有价值的时间,以前没有,以后可能更没有了
// 2003.12.x
// 因为要上学,所以能够静下心来学习的时间基本再也找不到了
// 2004.9.2 基本初步完成,尚未完成中断返回,尚未debug
// 2004.11.17 调试浮点程序通过,^_^ :) ^o^ ^0^ :(  >_< 他的缺点就是他的优点,我无法权衡,指令类暂时先稳定下来吧
// 当学生真是无奈,我在倒退..............我在放弃梦想...............
// 2005.3.28 不管怎样我要圆梦,我不能做个永远失败的人
// 效率低下,等出了1.0后是否大幅度修改
//////////////////////////////////////////////////////////////////////




// HEXBIN.h: interface for the HEXBIN class.
// HEX文件操作类1.0,暂时不支持扩展段和扩展线性地址
// 本代码由桃源村编写 2004.6.12
//
//////////////////////////////////////////////////////////////////////
/*
本文由AthlonxpX86(桃源村) 2004.6.11 翻译<>中的内容为译者加入的内容


问题:

什么是Intel HEX格式?

回答:

Intel HEX文件是记录文本行的ASCII文本文件,下面是Intel HEX文件格式,在Intel HEX文件中,每一行是一个HEX记录由十六进制数组成的机器码或者静态数据,Intel HEX文件经常被用于将程序或数据传输存储到ROM.EPROM,大多数编程器和模拟器使用Intel HEX文件.

记录格式:

一个Intel HEX文件可以包含任意多的十六进制记录,每条记录有五个域,下面是一个记录的格式.

:llaaaatt[dd...]cc

每一组字母是独立的一域,每一个字母是一个十六进制数字,每一域至少由两个十六进制数字组成,下面是字节的描述.

:	冒号是每一条Intel HEX记录的开始

ll	是这条记录的长度域,他表示数据(dd)的字节数目.

aaaa	是地址域,他表示数据的起始地址<如果是数据记录这表示将要烧录的这条记录中的数据在EPROM中的偏移地址,对于不支持扩展段地址和扩展线性地址的如89C51,这就是此条记录的起始地址>
tt	这个域表示这条HEX记录的类型,他有可能是下面这几种类型
00 ----数据记录<要分清楚这几种记录类型,后面会经常出现,不要搞混了>
01 ----文件结束记录<HEX文件的最后一条记录这个域是01>
02 ----扩展段地址记录
04 ----扩展线性地址记录

dd	是数据域,表示一个字节的数据,一个记录可能有多个数据字节,字节数目可以查看ll域的说明

cc	是效验和域,表示记录的效验和,计算方法是将本条记录冒号开始的所有对字母<不包括本效验字和冒号>所表示的十六进制数字<一对字母表示一个十六进制数,这样的一个十六进制数为一个字节>都加起来然后模除256得到的余数最后求出余数的补码即是本效验字节cc.
<例如:
:0300000002005E9D
cc=0x01+NOT((0x03+0x00+0x00+0x00+0x02+0x00+0x5E)%0x100)=0x01+0x9C=0x9D
C语言描述:
UCHAR cc;
cc=(UCHAR)~(0x03+0x00+0x00+0x00+0x02+0x00+0x5E);
cc++;
>

数据记录

Intel HEX文件由若干个数据记录组成,一个数据记录以一个回车和一个换行结束<回车为0x0D换行为0x0A>

比如下面的一条数据记录
:10246200464C5549442050524F46494C4500464C33
10是此行记录数据的字节数目
2462是数据在内存<将要烧写的EPROM地址>中的起始地址
00是记录类型00(是一个数据记录)
464C到464C是数据
33是此行记录的效验和

扩展线性地址记录(HEX386)
扩展线性地址记录也可以认为是32为地址记录和HEX386记录,这个纪录包含高16(16-31位)位数据地址,这种扩展的线性记录总是有两个字节数据,像下面这样:

:02000004FFFFFC
02是记录的数据字节数目
0000是地址域这在扩展地址记录中总是0000
04是记录类型04(扩展地址记录)
FFFF是高16位地址
FC是记录效验和,计算方法如下:
01h + NOT(02h + 00h + 00h + 04h + FFh + FFh)

当一个扩展线性地址记录被读到后,扩展线性地址记录的数据区域将被保存并应用到后面从Intel HEX文件中读出的记录,这个扩展线性记录一直有效,直到读到下一个扩展线性记录.


绝对内存地址 = 数据记录中的地址  +  移位后的扩展线性地址

                      |                     |

	           数据记录中的地址域   移位后扩展线性地址记录中的地址域

下面举例说明这个过程

从数据记录的地址域得到地址      	              2462
从扩展线性地址记录的地址域得到地址            FFFF
                                              --------
绝对内存地址                       	          FFFF2462


 
扩展段地址记录 (HEX86)

扩展段地址记录也可以认为是包含地址中4-19位的数据地址段,这个扩展段地址记录总是有两字节数据,如下:
:020000021200EA
02是记录中的数据字节数目
0000是地址域,在扩展段地址记录中,这个域总是0000
02是记录类型02(扩展段地址的标示)
1200是该段的地址
EA是效验和计算如下:
01h + NOT(02h + 00h + 00h + 02h + 12h + 00h).

当扩展段地址记录被读后,扩展段地址将被存储并应用到以后从Intel HEX文件读出的记录,这个段地址一直有效直到读到下一个扩展段地址记录

绝对内存地址 = 数据记录中的地址  +  移位后的扩展段地址

                      |                     |

	       数据记录中的地址域   移位后扩展段地址记录中的地址域

下面举例说明这个过程

从数据记录的地址域得到地址      	              2462
从扩展段地址记录的地址域得到地址                 1200
                                              --------
绝对内存地址                       	          00014462

文件结束记录(EOF)
一个Intel HEX文件必须有一个文件结束记录,这个记录的类型域必须是01,一个EOF记录总是这样:
:00000001FF
00是记录中数据字节的数目
0000这个地址对于EOF记录来说无任何意义
01记录类型是01(文件结束记录标示)
FF是效验和计算如下
01h + NOT(00h + 00h + 00h + 01h).
*/
#if !defined(AFX_HEXBIN_H__773948CC_061A_44EC_966D_55B2753BD48A__INCLUDED_)
#define AFX_HEXBIN_H__773948CC_061A_44EC_966D_55B2753BD48A__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define DEOF 0x00
#define NODEOF 0x01
struct Data
{
	UINT address;
	UCHAR data;
	UCHAR DataEOF;    //数据烧录结束,0表结束,1表未结束
};
struct record
{
	UCHAR ll;//此行数据记录长度
	UINT aaaa;//地址域
	UCHAR tt;//记录类型
	UCHAR * dd;//数据指针
	UCHAR cc;//效验和
	record * next;//下一个记录指针
};

class HEXBIN  
{
public:
	UINT GetMaxAddr();
	UINT GetHexDataSize();
	record * head;
	record * noncep;//当前记录指针
	Data * pData;
	UCHAR * Databuf;
	UINT HEXSIZE;//数据域大小
	UINT MAXADDR;//HEX最大地址
	Data * GetNextData();//得到下一个数据
	int HEXTOBIN(TCHAR * pPath);//HEX转BIN文件
	int HEXTOBINBUF(BYTE * pBUF,DWORD Size);//HEX转BIN缓冲
	int LoadHEXFile(TCHAR * pPath);//加载HEX文件
	HEXBIN();
	HextoDec(TCHAR * p);//十六进制字符串转数字
	virtual ~HEXBIN();

protected:
	UINT offset;//记录中数据域相对偏移
};

#endif // !defined(AFX_HEXBIN_H__773948CC_061A_44EC_966D_55B2753BD48A__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -