搜索
bottom↓
回复: 83

请弄过汇编的提个意见,关于读5000行汇编东东...

[复制链接]

出0入0汤圆

发表于 2010-3-8 16:45:08 | 显示全部楼层 |阅读模式
这个程序以前是8031+外部存储器的机器,老机器,外国人的,我们学习中。
里边有8155,8255等等,程序有5000行汇编,汇编是反汇编来的,15k程序,RAM基本都用完,没有解释,
请问读懂这个程序是否困难,去交给电子市场的话我要求能提供详细解释(详细到我能修改里边的参数),大概的报价是多少?
如果我们自己读这个程序(我们没有很丰富的汇编经验,有丰富的C,外设控制,多种MCU经验),是否可行,大概多久能看出门道?
请大家评估下给个参考意见。谢谢!

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2010-3-8 16:49:21 | 显示全部楼层
5000行,还是反汇编过来的,没注释.....-_-||
帮楼主顶一下,期待牛人。

出0入42汤圆

发表于 2010-3-8 16:55:54 | 显示全部楼层
omg,这个价格肯定不便宜...

先想下5000行无注释的C...

出0入0汤圆

发表于 2010-3-8 17:26:01 | 显示全部楼层
要看你们的时间与耐心了,都有代码,总能读懂吧,只是时间上可能会比较久,另外个人估计大多数时间,可能会浪费在分析算法上,还有关键是读懂过后要干什么。

出0入0汤圆

发表于 2010-3-8 17:36:15 | 显示全部楼层
我有个朋友是做老火鸡的他就把5000行的汇编东东加上了注解,但加了注解我看的还是晕

出0入0汤圆

发表于 2010-3-8 17:48:53 | 显示全部楼层
如果对速度和容量没有要求,可以用高一级的CPU(如AVR甚至STM32)来模拟51的指令码

当然,在成本可以接受的范围内,不过用了8155和8255,估计不会在乎成本

出0入0汤圆

 楼主| 发表于 2010-3-8 18:02:05 | 显示全部楼层
楼上讲的怎么模拟法?能否再讲些? 那个程序好多lcall 

出0入0汤圆

 楼主| 发表于 2010-3-8 18:04:03 | 显示全部楼层
我们读懂它是为了解他们是基于什么原理来测量的 等等

出0入0汤圆

发表于 2010-3-8 18:08:40 | 显示全部楼层
如 MOV A,#3  改成 LDI R16,3 (AVR) 或 ACC = 3; (C语言)

LCALL 0800H 改成  RCALL SUB0800 或   sub0800();

不然你贴一小段上来

出0入0汤圆

发表于 2010-3-8 18:11:44 | 显示全部楼层
等完全转换到AVR或C语言,就可以用AVR或STM32的仿真器单步运行,到时就可以把算法找出来了

出0入0汤圆

 楼主| 发表于 2010-3-8 18:22:04 | 显示全部楼层
主意不错 我明天试试 谢谢 明早我贴点出来 你能指点下就太好了 

出50入0汤圆

发表于 2010-3-8 18:33:05 | 显示全部楼层
看反汇编确实费神,要“非常”了解这个产品,包含功能细分和实现过程;
你还要确定这个反汇编能编译通过,而且在机器运行正常。
很多反汇编软件把表格反为代码,或把代码反为表格,这个最头痛。
15K不算太大,估计2个月能看个大概,真正熟悉代码估计要半年。

出0入0汤圆

发表于 2010-3-8 19:03:08 | 显示全部楼层
51的15k二进制码程序,除非带大量表格,否则反汇编后至少7000行。
没到电子市场搞过这种业务,不知道大概的报价。
交给我的话,1月之内能提供详细解释,报价10000元。
QQ:150276928,请留言。

出0入42汤圆

发表于 2010-3-8 19:08:24 | 显示全部楼层
对硬件做了解
对功能了解
试着写下这个程序

从io口入手

出0入0汤圆

发表于 2010-3-8 19:14:07 | 显示全部楼层
如果是人一行一行写的汇编 其他人还能理解 机器反汇编的就算了把

出0入0汤圆

发表于 2010-3-8 19:16:57 | 显示全部楼层
回复【13楼】xuhai777
-----------------------------------------------------------------------


如果知道这个产品是做什么的,有什么功能,和要测量什么量,或者还可以评估多久可以分析出来,

现在楼主什么都没说,你一个月就能分析出来,太利害了,不知你是属牛的还是属驴的?

出0入0汤圆

 楼主| 发表于 2010-3-8 20:16:53 | 显示全部楼层
这个产品测量的是实时的电压,电流,是否和相位有关我们也不知道,这也是我们想知道的。
根据电压电流可能会按照一些算法来获得电阻,或者输出功率,
具体的我们也不清楚什么样的电流/电压 输出什么样的功率,以及采集的数据有没有被很细致的优化(比如被分段线性化)!
这也是我们想了解代码的原因。

我们的老板并不希望重写,他们认为老外推了十几年的东西肯定比随便找个人写的要可靠,这种观点我认为是正确的,这也是我们想仔细学习老外的程序的原因。看他们具体采集了什么,处理了什么。

出0入42汤圆

发表于 2010-3-8 20:34:14 | 显示全部楼层
同问:义隆,1000行大概什么价位?
测量市电电压的电路
电路比较简单

出0入0汤圆

发表于 2010-3-8 20:36:28 | 显示全部楼层
1.想想这程序设计的年代使用的是什么编译器,比如汇编编译器是怎样的,C编译器是怎样的。

2.分析其中一部代码,看看这程序是否为汇编或C编译而成。如果是汇编,那就分析吧;如果是C,那就复杂了。

出0入0汤圆

 楼主| 发表于 2010-3-8 21:00:24 | 显示全部楼层
电路图暂时还没有画,老实说我还没有仔细看电路图
基本上就是AD0832,8155之类,就是有比较多的扩展,我们现在想评估下看懂程序是否可能...
如果可能,那么仔细重画原理图,如果困难,那就搁置吧...那是一个朋友弄的东东,

出0入0汤圆

发表于 2010-3-8 21:08:09 | 显示全部楼层
如果将来要自己生产这台机器,建议先转到STM32等外设丰富的新的MCU上,这样原本的8155,8255,A/D,D/A...

都可以转到MCU内,可以省下不少的成本

当然,同为51核的C8051系列也可以考虑,不过开发环境和仿真工具没有像AVR或STM32那么普及,芯片成本也高

出0入0汤圆

发表于 2010-3-8 21:09:16 | 显示全部楼层
回复【16楼】xiejun 业余程序员
-----------------------------------------------------------------------

我是来自广西的,现在深圳。
看到你也是广西-->深圳,本来还有点好感,可看到你的回复,好感值前面加了个负号。
井底之蛙是不值得辩论的。
我很负责的对你说:我是属马的。

出0入0汤圆

发表于 2010-3-8 22:54:23 | 显示全部楼层
回复【23楼】xuhai777
-----------------------------------------------------------------------

抱歉,我的回复并没有恶意,我的意思很明白呀,不是很牛,就是很辛苦。

我相信你也是有工作的,业余时间分析,如果不是十分牛的话,肯定要花很多时间去分析,一个月时间除掉上班,

已经没有多少了。表示和驴一样辛苦而已。

出0入0汤圆

发表于 2010-3-9 02:28:49 | 显示全部楼层
没有对相应电路的相当熟悉,对产品功能相当了解,1个月的时间是搞不出东西的。
把hex反成正确的ASM都非常的困难,何况反出来的汇编里太多的jmp ,Ljmp ,Lcall之类
的天马行空语句,看得头晕。

出0入0汤圆

发表于 2010-3-9 07:27:48 | 显示全部楼层
这要看原来程序是用何种语言写的.
如果是用汇编写的,更与写程序的人有关,你甚至能感觉出哪些段是一个人写,另一些段是另一个人写的.是不是故意搞了些反编译技巧.
如果是用C写的,哪就非常有规律可循.
现在的反编译软件,基本可以做到反出来的代码,不管是否准确地区分了数据与代码,但得到的代码汇编成HEX->BIN后,与EEPROM中的内容相同,一个字不差.然后你再一段一段地分析调试,每改一次,就汇编后与EPROM对比..其中把外设地址首先搞清楚.再根据外设地址反猜程序功能,程序轮廓慢慢地就出来了.时间长短就无法说了,看你的目的了.

出0入0汤圆

发表于 2010-3-9 09:21:46 | 显示全部楼层
楼主在哪个城市?

出0入0汤圆

 楼主| 发表于 2010-3-9 12:40:54 | 显示全部楼层
南京

出0入0汤圆

发表于 2010-3-9 13:39:39 | 显示全部楼层
楼主不是要贴一小段汇编上来吗? 还是放弃了?

出0入0汤圆

发表于 2010-3-9 13:42:04 | 显示全部楼层
8031,还汇编,愁死。

出0入0汤圆

发表于 2010-3-9 13:58:01 | 显示全部楼层
分析这样的东西,首先还是有完整的硬件原理图。先熟悉操作逻辑和硬件的端口动作,才好看汇编代码的。否则就会一头雾水,看了后面忘了前面。记得原来也干个这样的事情,太损伤脑细胞了。有可能的话,还是从新写代码吧。事半功倍。

出0入0汤圆

发表于 2010-3-9 15:40:20 | 显示全部楼层
【10楼】 kl818bc000 我不是马甲
   为什么要模拟51的指令码,还要等完全转换到AVR或C语言,就可以用AVR或STM32的仿真器单步运行,直接用51的仿真器单步运行不是更好吗?

  51的仿真器一大把,万利的,伟福的,菊阳的有的是,而且从描述来看.这个可能是AT89C52的芯片的使用了外部总线,这适合这些仿真器.

  vipcff 我觉得,这个不会太复杂,过期的MCU技术还是要比现在的落后很多的,而且很多芯片业不好买了,买到也是拆机件,质量没有保证

出0入0汤圆

发表于 2010-3-9 16:58:48 | 显示全部楼层
如果你懂得控制过程,读别人程序,不如自己写,因为别人的算法会把你搞晕

如果你不懂得控制过程,读懂程序的可能=0

出0入0汤圆

 楼主| 发表于 2010-3-9 17:27:24 | 显示全部楼层
谢谢各位啊 在下做事喜欢拖 明天放代码啊 有人说重写我们先不考虑 原因是我们看代码的目的就是为学习算法和控制策略 而且我们不知道机器的运行流程  既不知道机器什么时候读什么 什么时候输出什么等等 

出0入0汤圆

发表于 2010-3-9 17:43:39 | 显示全部楼层
正在进行时

出0入0汤圆

发表于 2010-3-9 17:51:36 | 显示全部楼层
目的就是为学习算法和控制策略

这个最好是自己读,别人读完了,是别人研究的.

我个人的经验,学习算法最好从原理出发,控制策略,看他的动作逻辑,不要说汇编高级语言的算法没有原理支持,你都很难看懂
给你一个很简单的代码,你看看他是在干什么?
#include <iostream>
#include <cmath>
using namespace std;

double root(double a,int n)
{
const double error = 1e-14;
double left,right,x0,x1,ef;
left = 1;
right = 1000;
x0 = right;
do
{
   x1=right-(exp(n*log(right))-a)/n/exp((n-1)*log(right));
   if( x1<=left || x1>=right )
    x1 = (left+right)/2;
   ef = x1-x0;
   if( ef < 0 )
    ef = -ef;
   x0 = x1;
   if( exp(n*log(x1)) < a )
    left = x1;
   else
    right = x1;
}
while( ef > error );
return x1;
}

int main(int argc,char ** argv)
{
double a;
int n;
cout<<"a = ";
cin>>a;
cout<<"n = ";
cin>>n;
cout<<root(a,n)<<endl;
return 0;
}

出0入0汤圆

发表于 2010-3-9 20:32:08 | 显示全部楼层
劝LZ还是找别的方法吧
不懂控制,靠看代码反推控制。。。
不要说是汇编,就是C写的,你徒劳的可能就是99.9999%

出0入0汤圆

 楼主| 发表于 2010-3-9 20:44:31 | 显示全部楼层
楼上有理 楼上的意见是走其他的路,其他人的意见呢?大家继续。
这个机器就像是我国很牛的逆向工程?呵呵,我们老板好像三个月就能逆向一台,只是基于送到电子商城全拷贝,但是现在想调参数,更新,所以我们在寻找可行的更新方法。读懂他们的产品也是一种路,虽然我个人不看好,我个人倾向于独立开发而不是学习老外的成品,所以到这里来请求大家的观点。

出0入0汤圆

发表于 2010-3-9 21:39:33 | 显示全部楼层
回复【32楼】zhxzhx 一丁
【10楼】 kl818bc000 我不是马甲
   为什么要模拟51的指令码,还要等完全转换到AVR或C语言,就可以用AVR或STM32的仿真器单步运行,直接用51的仿真器单步运行不是更好吗?
  51的仿真器一大把,万利的,伟福的,菊阳的有的是,而且从描述来看.这个可能是AT89C52的芯片的使用了外部总线,这适合这些仿真器.
  vipcff 我觉得,这个不会太复杂,过期的MCU技术还是要比现在的落后很多的,而且很多芯片业不好买了,买到也是拆机件,质量没有保证  

-----------------------------------------------------------------------

楼主说了,是8031,不是AT89C52,8031是不带程序存储器(ROMLESS)的8051

标准51由于没有内嵌类似JTAG的仿真功能,第三方的仿真器价格和功能,是不能和内置JTAG且已经开源的

AVR JTAG-ICE和ARM JLINK相比拟的

而且楼主的8031需要的外设多,才建议直接转到容量大,外设丰富且价格便宜的AVR或STM32

直接逆向没什么难度,很多人都能作,但很多元器件都已经不好买且贵,如果能转换到主流的CPU,成本就可以降下来,先抢到市场

再借用仿真器慢慢读懂其算法,就可以调参数,加功能

出0入0汤圆

发表于 2010-3-10 00:42:03 | 显示全部楼层
【39楼】 kl818bc000 我不是马

这你就老外了,8031不带程序存储器的仿真器,比JTAG的要好用的多了,看来你没有用过51的仿真器啊!

标准51的仿真器,就是仿真cpu,拔掉真的cpu,插上仿真头,8155,8255,什么的都是真实时效的运行

你看看仿真器的功能:

条件断点
    多种采样方式便于对用户板不同的存储器进行条件触发或者条件断点,又可以使用“事件计数”功能,通过指定程序第几次执行到指定地址发生时,触发逻辑分析工作,然后根据事件发生的前后几次采样数据,进行总线采样的过程分析。
    触发逻辑分析也可以对 XTATA 外部数据存储器、CODE 程序存储器、SFR 特殊功能存储器、REG 内部存储器、XDATA数据范围、CODE程序范围、LAPOD(外接测试探勾信号)输入,进行 4种条件采样分析。

代码覆盖:
    在运行复杂结构的程序时,可以实时地了解程序的执行情况,可以动态地观察到指定条件下,某段代码是否被执行了。在用户程序运行时,如用单步、断点或全速运行,利用该功能随时观察到程序执行情况,能观察到在源程序, CPU窗口、CODE代码区窗口、程序运行过的指令以不同颜色作标记显示。例如:中断有没有响应,只需看中断子程序有没有变颜色,子程序有无调用,只需看子程序模块有无变颜色即可。

程序时效分析:
    分析程序中,过程、函数以及每条指令的运行时间,执行次数及占整个程序程序运行时间的百分比,了解到一个程序多个函数中某个函数运行的效率有多高,执行了多长时间,代码覆盖优化到什么程度,利用该功能就可以优化程序,进一步改善程序的性能,从而改善程序的结构,开发出更有效、更稳定的程序。对提高程序效率,检查程序错误提供帮助。

数据时效分析:
    统计每个变量、存贮单元的访问次数及占整个程序访问次数的百分比,即统计分析当前运行的程序中各变量、数据单元是否被读/写和读/写的次数及读/写次数占总读/写次数的百分比,变量是被写过,还是变量被读过,变量是先写后读,还是先读后写,统计出读/写的次数。如:对某一段XDATA变量检查是否被读/写过,是否读/写正确,可利用该功能完成。对提高程序效率、检查程序错误提供帮助。

影子存储器:
    在用户程序运行时,可以观察外部存贮器内容的变化,设计师无须停下程序,也能直观、动态监视外部数据变化。影子存储器就是在仿真环境中为外部存储器建立一个影子,可以在程序运行时,动态地观察到外部存储器的状态,利用该功能可对调试实时数据采集控制程序提供有力的帮助。

条件断点:支持数据断点、程序断点、内部特殊功能寄存器断点、内部寄存器断点、数据范围断点、程序范围断点。外部测试点断点及最多65536次断点计数。

利用程序范围断点,立刻就可以发现程序跑飞.

出0入0汤圆

发表于 2010-3-10 09:26:05 | 显示全部楼层
我用过Z80,8086/88的硬件仿真器(ICE,In Circuit Emulator),你说的这些功能也大部份都有

的确没用过51的仿真器,我认为51,96/196这些MCU没必要用ICE,因为真正用到那么复杂的系统,就不必用51

MCU有MCU的用途,MPU有MPU的定位,不要期望51能吃下所有的产品线


还有,你上面提到具备这些功能的仿真器要多少米?还有,花那么多钱买了这个仿真器,只能开发传统纯8051,值得吗?

就算研究完算法,真正要作产品,你还会用8031+8155+...来生产吗?就算你再用的是增强型51(如C8051或STC或笙泉)

这个51仿真器还有用吗?

出0入0汤圆

 楼主| 发表于 2010-3-10 09:55:05 | 显示全部楼层
0000: 02 00 28  LJMP  0028H
0003:    74 04  MOV   A,#04H
0005: 02 06 DC  LJMP  06DCH
0008:       00  NOP
0009:       00  NOP
000A:       00  NOP
000B:    74 06  MOV   A,#06H
000D: 02 06 DC  LJMP  06DCH
0010:       00  NOP
0011:       00  NOP
0012:       00  NOP
0013:    74 0C  MOV   A,#0CH
0015: 02 06 DC  LJMP  06DCH
0018:       00  NOP
0019:       00  NOP
001A:       00  NOP
001B: 02 22 49  LJMP  2249H
001E:       00  NOP
001F:       00  NOP
0020:       00  NOP
0021:       00  NOP
0022:       00  NOP
0023:    74 06  MOV   A,#06H
0025: 02 06 DC  LJMP  06DCH
0028: 75 81 69  MOV   SP,#69H
002B: 12 17 22  LCALL 1722H
002E: 12 04 22  LCALL 0422H
0031:    D2 AF  SETB  EA
0033: 12 0A F5  LCALL 0AF5H
0036:    D2 10  SETB  22H.0
0038: 12 10 F2  LCALL 10F2H
003B: 90 80 02  MOV   DPTR,#8002H
003E:       E0  MOVX  A,@DPTR
003F: 30 E7 69  JNB   ACC.7,00ABH
0042: 12 07 B8  LCALL 07B8H
0045: 12 0D 37  LCALL 0D37H
0048: 12 04 92  LCALL 0492H
004B:    D2 1D  SETB  23H.5
004D: 12 0D 44  LCALL 0D44H
0050: 12 17 22  LCALL 1722H
0053: 12 16 AB  LCALL 16ABH
0056: 12 01 8F  LCALL 018FH
0059: 12 08 BF  LCALL 08BFH
005C:    E5 23  MOV   A,23H
005E:    44 E0  ORL   A,#0E0H
0060:       F4  CPL   A
0061:    70 EA  JNZ   004DH
0063: 12 0A 05  LCALL 0A05H
0066: 12 09 15  LCALL 0915H
0069: 12 07 B8  LCALL 07B8H
006C: 12 01 8F  LCALL 018FH
006F: 12 07 F8  LCALL 07F8H
0072: 12 0E FC  LCALL 0EFCH
0075: 12 0D 53  LCALL 0D53H
0078: 12 0E 6F  LCALL 0E6FH
007B: 12 01 E6  LCALL 01E6H
007E: 12 10 F2  LCALL 10F2H
0081:       C3  CLR   C
0082: 12 12 0C  LCALL 120CH
0085: 12 02 4B  LCALL 024BH
0088: 12 12 9F  LCALL 129FH
008B: 12 07 17  LCALL 0717H
008E: 12 11 91  LCALL 1191H
0091: 12 0F AC  LCALL 0FACH
0094: 12 0B 49  LCALL 0B49H
0097: 12 05 CF  LCALL 05CFH
009A: 12 17 05  LCALL 1705H
009D: 12 17 15  LCALL 1715H
00A0: 12 08 9F  LCALL 089FH
00A3:    D2 A8  SETB  EX0
00A5:    C2 B4  CLR   P3.4
00A7:    D2 B4  SETB  P3.4
00A9:    80 BE  SJMP  0069H
00AB:    74 4C  MOV   A,#4CH
00AD:    24 01  ADD   A,#01H
00AF:    F5 58  MOV   58H,A
00B1:    74 17  MOV   A,#17H
00B3:    34 00  ADDC  A,#00H
00B5:    F5 59  MOV   59H,A
00B7: 75 8B 9F  MOV   TL1,#9FH
00BA: 75 8D AE  MOV   TH1,#0AEH
00BD:    D2 AB  SETB  ET1
00BF:    D2 8E  SETB  TR1
00C1:    74 FF  MOV   A,#0FFH
00C3: 12 17 2E  LCALL 172EH
00C6: 12 07 B8  LCALL 07B8H
00C9:    74 0E  MOV   A,#0EH
00CB: B5 18 F8  CJNE  A,18H,00C6H
00CE:       E4  CLR   A
00CF: 12 17 2E  LCALL 172EH
00D2: 12 07 B8  LCALL 07B8H
00D5:       E4  CLR   A
00D6: B5 18 F9  CJNE  A,18H,00D2H
00D9: 12 18 5A  LCALL 185AH
00DC: 12 01 8F  LCALL 018FH
00DF: 12 25 D2  LCALL 25D2H
00E2:    E5 23  MOV   A,23H
00E4:    44 EE  ORL   A,#0EEH
00E6:       F4  CPL   A
00E7:    70 F0  JNZ   00D9H
00E9: 12 26 94  LCALL 2694H
00EC: 12 17 D9  LCALL 17D9H
00EF: 12 07 B8  LCALL 07B8H
00F2: 12 23 E6  LCALL 23E6H
00F5: 12 01 8F  LCALL 018FH
00F8: 12 07 F8  LCALL 07F8H
00FB: 12 1C 21  LCALL 1C21H
00FE: 12 1D 9E  LCALL 1D9EH
0101: 12 1E 2E  LCALL 1E2EH
0104: 12 28 C5  LCALL 28C5H
0107: 12 27 21  LCALL 2721H
010A: 12 25 F8  LCALL 25F8H
010D: 12 1A 8C  LCALL 1A8CH
0110: 12 18 06  LCALL 1806H
0113: 12 24 AB  LCALL 24ABH
0116: 12 19 BB  LCALL 19BBH
0119: 12 24 FF  LCALL 24FFH
011C: 12 0B 49  LCALL 0B49H
011F:    D2 01  SETB  20H.1
0121: 12 05 CF  LCALL 05CFH
0124: 12 2A 89  LCALL 2A89H
0127: 12 25 C3  LCALL 25C3H
012A:    80 C3  SJMP  00EFH
012C: 75 81 69  MOV   SP,#69H
012F:    79 04  MOV   R1,#04H
0131:    7B 58  MOV   R3,#58H
0133: 12 05 F9  LCALL 05F9H
0136:       F7  MOV   @R1,A
0137:       0B  INC   R3
0138:       09  INC   R1
0139: BB D2 F7  CJNE  R3,#0D2H,0133H
013C:    80 FE  SJMP  $
013E:    C2 94  CLR   P1.4
0140:    D2 95  SETB  P1.5
0142:    E5 30  MOV   A,30H
0144: 90 80 01  MOV   DPTR,#8001H
0147:    C2 E6  CLR   ACC.6
0149:       F0  MOVX  @DPTR,A
014A:       E8  MOV   A,R0
014B: 90 14 F8  MOV   DPTR,#14F8H
014E:       93  MOVC  A,@A+DPTR
014F:    78 05  MOV   R0,#05H
0151:       13  RRC   A
0152:    92 95  MOV   P1.5,C
0154:       00  NOP
0155:    D2 94  SETB  P1.4
0157: B8 01 02  CJNE  R0,#01H,015CH
015A:    80 04  SJMP  0160H
015C:    C2 94  CLR   P1.4
015E:    D8 F1  DJNZ  R0,0151H
0160:    D2 95  SETB  P1.5
0162:    A2 95  MOV   C,P1.5
0164:    C2 94  CLR   P1.4
0166:       E4  CLR   A
0167:    78 08  MOV   R0,#08H
0169:    D2 94  SETB  P1.4
016B:       00  NOP
016C:    C2 94  CLR   P1.4
016E:       00  NOP
016F:    A2 95  MOV   C,P1.5
0171:       33  RLC   A
0172:    D8 F5  DJNZ  R0,0169H
0174:       F8  MOV   R0,A
0175:    E5 30  MOV   A,30H
0177: 90 80 01  MOV   DPTR,#8001H
017A:    D2 E6  SETB  ACC.6
017C:       F0  MOVX  @DPTR,A
017D:       E8  MOV   A,R0
017E:       22  RET
017F: 85 42 3E  MOV   3EH,42H
0182: 85 43 3F  MOV   3FH,43H
0185: D5 3C 06  DJNZ  3CH,018EH
0188: 75 3C 18  MOV   3CH,#18H
018B: 85 41 3D  MOV   3DH,41H
018E:       22  RET
018F:    7B 03  MOV   R3,#03H
0191:    7C 00  MOV   R4,#00H
0193:    7D 08  MOV   R5,#08H
0195:    7E 00  MOV   R6,#00H
0197:    7F 00  MOV   R7,#00H
0199:    A8 04  MOV   R0,04H
019B: 12 01 3E  LCALL 013EH
019E:       2E  ADD   A,R6
019F:       FE  MOV   R6,A
01A0:       E4  CLR   A
01A1:       3F  ADDC  A,R7
01A2:       FF  MOV   R7,A
01A3:    A8 05  MOV   R0,05H
01A5:       08  INC   R0
01A6:    D8 FE  DJNZ  R0,$
01A8:    DD EF  DJNZ  R5,0199H
01AA:    78 03  MOV   R0,#03H
01AC:       C3  CLR   C
01AD:       EF  MOV   A,R7
01AE:       13  RRC   A
01AF:       FF  MOV   R7,A
01B0:       EE  MOV   A,R6
01B1:       13  RRC   A
01B2:       FE  MOV   R6,A
01B3:    D8 F7  DJNZ  R0,01ACH
01B5:       E4  CLR   A
01B6:       3E  ADDC  A,R6
01B7:       FE  MOV   R6,A
01B8:       EC  MOV   A,R4
01B9:    24 41  ADD   A,#41H
01BB:       F8  MOV   R0,A
01BC:       EE  MOV   A,R6
01BD:       26  ADD   A,@R0
01BE:       13  RRC   A
01BF:    34 00  ADDC  A,#00H
01C1:       F6  MOV   @R0,A
01C2:       0C  INC   R4
01C3:    DB CE  DJNZ  R3,0193H
01C5: 12 01 7F  LCALL 017FH
01C8:       22  RET
01C9: 20 0C 03  JB    21H.4,01CFH
01CC:    D2 2B  SETB  25H.3
01CE:       22  RET
01CF: 30 0F 13  JNB   21H.7,01E5H
01D2: 20 0D 10  JB    21H.5,01E5H
01D5:    D2 0D  SETB  21H.5
01D7:    D2 0E  SETB  21H.6
01D9: 85 3D 45  MOV   45H,3DH
01DC:    C2 22  CLR   24H.2
01DE:    C2 23  CLR   24H.3
01E0:    D2 16  SETB  22H.6
01E2: 75 51 0A  MOV   51H,#0AH
01E5:       22  RET
01E6: 20 27 53  JB    24H.7,023CH
01E9:    C2 0F  CLR   21H.7
01EB:    C2 13  CLR   22H.3
01ED:    C2 14  CLR   22H.4
01EF:    C2 15  CLR   22H.5
01F1: 75 82 D2  MOV   DPL,#0D2H
01F4: 12 06 C2  LCALL 06C2H
01F7:       F8  MOV   R0,A
01F8:       A3  INC   DPTR
01F9: 12 06 C2  LCALL 06C2H
01FC:       F9  MOV   R1,A
01FD:    E5 3D  MOV   A,3DH
01FF: 20 0C 14  JB    21H.4,0216H
0202: 30 0F 06  JNB   21H.7,020BH
0205:    24 03  ADD   A,#03H
0207:    50 02  JNC   020BH
0209:    74 FF  MOV   A,#0FFH
020B:       C3  CLR   C
020C:       98  SUBB  A,R0
020D:    40 06  JC    0215H
020F:    D2 0F  SETB  21H.7
0211:    D2 13  SETB  22H.3
0213:    C2 0E  CLR   21H.6
0215:       22  RET
0216:       C3  CLR   C
0217:       98  SUBB  A,R0
0218:    40 F5  JC    020FH
021A:       C3  CLR   C
021B:    E5 3D  MOV   A,3DH
021D:       99  SUBB  A,R1
021E:    40 07  JC    0227H
0220:    D2 0F  SETB  21H.7
0222:    D2 14  SETB  22H.4
0224:    C2 0E  CLR   21H.6
0226:       22  RET
0227: 30 0E 0C  JNB   21H.6,0236H
022A:       C3  CLR   C
022B:    E5 3D  MOV   A,3DH
022D:    95 45  SUBB  A,45H
022F:    40 E4  JC    0215H
0231:       C3  CLR   C
0232:    94 08  SUBB  A,#08H
0234:    40 DF  JC    0215H
0236:    D2 0F  SETB  21H.7
0238:    D2 15  SETB  22H.5
023A:    C2 0E  CLR   21H.6
023C:       22  RET
023D:    78 14  MOV   R0,#14H
023F:    79 03  MOV   R1,#03H
0241: 90 14 3B  MOV   DPTR,#143BH
0244:       E6  MOV   A,@R0
0245:       93  MOVC  A,@A+DPTR
0246:       F6  MOV   @R0,A
0247:       08  INC   R0
0248:    D9 FA  DJNZ  R1,0244H
024A:       22  RET
024B:       E4  CLR   A
024C: 30 0C 39  JNB   21H.4,0288H
024F: 20 13 36  JB    22H.3,0288H
0252:    74 0A  MOV   A,#0AH
0254: 20 14 2A  JB    22H.4,0281H
0257: 75 82 D2  MOV   DPL,#0D2H
025A: 12 06 C2  LCALL 06C2H
025D:       F9  MOV   R1,A
025E:       A3  INC   DPTR
前310行的程序

出0入0汤圆

发表于 2010-3-10 10:56:45 | 显示全部楼层
呵呵,好久没看到这么亲切的汇编代码了。开始用51时,就是先用汇编的。

0028前面是中断向量入口,
然后是堆栈指针赋值,开全局中断,读外部总线的数据,调整TIMER1。程序里用了大量的子程序,到方便阅读,因为模块化的设计可以使得程序的功能单元相对简单。

还是要配合硬件图才好分析了。否则谁知道里面的标志位和IO在做什么呢。

出0入170汤圆

发表于 2010-3-10 11:13:13 | 显示全部楼层
要配合硬件图才好分析

出0入0汤圆

发表于 2010-3-10 11:26:01 | 显示全部楼层
00EF: 12 07 B8  LCALL 07B8H
00F2: 12 23 E6  LCALL 23E6H
00F5: 12 01 8F  LCALL 018FH
00F8: 12 07 F8  LCALL 07F8H
00FB: 12 1C 21  LCALL 1C21H
00FE: 12 1D 9E  LCALL 1D9EH
0101: 12 1E 2E  LCALL 1E2EH
0104: 12 28 C5  LCALL 28C5H
0107: 12 27 21  LCALL 2721H
010A: 12 25 F8  LCALL 25F8H
010D: 12 1A 8C  LCALL 1A8CH
0110: 12 18 06  LCALL 1806H
0113: 12 24 AB  LCALL 24ABH
0116: 12 19 BB  LCALL 19BBH
0119: 12 24 FF  LCALL 24FFH
011C: 12 0B 49  LCALL 0B49H
011F:    D2 01  SETB  20H.1
0121: 12 05 CF  LCALL 05CFH
0124: 12 2A 89  LCALL 2A89H
0127: 12 25 C3  LCALL 25C3H
012A:    80 C3  SJMP  00EFH

这一段是主程序,之前的是中断向量和初始程序,之后的是子程序

是用汇编写的,简洁清楚,作者是个高手,不过建议再用IDA反汇编一次,会比这样清楚很多

要转成C或AVR应该没问题

出0入85汤圆

发表于 2010-3-10 11:46:10 | 显示全部楼层
分析反汇编最好是需要产品说明书和原理图的,分析过一个代码量大概3000行

出0入84汤圆

发表于 2010-3-10 12:30:23 | 显示全部楼层
分析过别人用C写的反汇编的程序,5K行,用一个月,没看懂,重新编写用了1周,搞定

出0入0汤圆

发表于 2010-3-11 00:14:45 | 显示全部楼层
【41楼】 kl818bc000 我不是马甲

   51仿真器,直接就可以分析了,这个程序直接和众多外部硬件打交道,这些外部设备你如何在AVR或STM内部建立?

还有,代码都没有分析完,你怎么转换?就算你一对一的翻译了,你能保证功能正确?简单的例子,51循环100次的延时和AVR循环100次的延时时间能一样?

还有仿真器是钱,难道花费的时间就不是钱?月薪1万的工程师,一个工作日的成本,基本就是500元了!

很怀疑你干没干过这种活!

有你那个麻烦,还不如在PROTEUS上仿真,这还是个路子

出0入0汤圆

发表于 2010-3-11 08:36:45 | 显示全部楼层
##########################################

   硬件作法请看下面59楼介绍

##########################################

速度快的可以模拟速度慢的,容量大的可以模拟容量小的,如果速度真有问题,把转成的AVR汇编后面加几个NOP就成了

工控产品一般都是事件(如中断,外设,输入)驱动的,也都会留一定的余量,除非是用来模拟类似USB这类严格的时序,一般都可以


这个方法和硬件仿真器一样可以马上在原来板子上电验证,软件仿真就作不到

但也可以马上重新画板,把已经读懂的硬件用AVR内的存储外设取代(如ROM,RAM,ADC,8255..),作成产品上市销售,这就是硬件仿真器作不到的

除非楼主的老板只要楼主读懂程序,不想生产出产品来盈利,不过那是不可能的


当然,用C8051这类增强型51也行,只是开发环境和仿真工具不像AVR/STM32选择那么多又便宜

老板最在乎的芯片成本也无法和AVR/STM32同级的相比


还有,千万不要认为在中国的每个工程师都有一万的月薪

出0入0汤圆

发表于 2010-3-11 14:14:12 | 显示全部楼层
【49楼】 kl818bc000 我不是马甲

你还是纸上谈兵,根本没有实际经验.

你不知道8051要干什么,你模拟个屁,你说的是在知道8051个工作流程的情况下的工作,现在是要知道8051在干什么
还以延时为例,你不知道51延时了多长时间,你怎么确定AVR的延时时间?

你的方法,勉强可以模拟一下逻辑,但是时序你没有办法确定.

出0入0汤圆

发表于 2010-3-11 21:34:47 | 显示全部楼层
8051是12分频的MCU,指令周期都是晶振固定的12倍数,用固定1-3晶振周期的AVR指令来模拟,这有什么难的?

##########################################

   软件作法请看下面59楼介绍

##########################################

至少我把硬件和软件的解决方法公开说出来了,你除了叫大家花大钱买硬件仿真器外,你还贡献了什么?

你说我是纸上谈兵,难道要我放下手边的工作,花时间无偿替楼主改成AVR代码,且可以运行,才算不是纸上谈兵吗?

买了你说的硬件仿真器,也不等于楼主的问题解决了

出0入42汤圆

发表于 2010-3-11 23:22:52 | 显示全部楼层
程序写的挺清楚的,应该可以能看得懂

出0入0汤圆

发表于 2010-3-12 00:16:02 | 显示全部楼层
【51楼】 kl818bc000 我不是马

   这个不是仿一个单片机的问题,你外设怎么仿?
   PROTEUS做的不错了吧?计算机的CPU比AVR强大的多了吧?他仿真的还不能达到真正的实时运行的性能,
   单片机不光有指令,它还有一套特定的寄存器结构,一套特定的寻址方式,一套特定的外设操作方法,
不是你认为的替换一下指令就行的,比如说51的ALE信号,51每执行一次取指令操作,ALE就会产生一个脉冲,这个脉冲可以做总线的锁存信号,在LZ的电路上,它就应该接在74LS373的11脚上,也可以做为一些AD的时钟信号,它是和51的总线操作相关联的,并不是一个单纯的频率信号,你不能用一个频率信号来代替,同时他还是一个高速信号,12M的51,这个信号的频率是1M,此外,还有PSEN信号,指示单片机在读出ROM还是RAM的,还有RD,RW,这些信号8155,8255都要用到,这些,你这怎么模仿?

  另外,能完成LZ功能要求的仿真器并不贵,Monitor-51就行,软件就是Keil C51,成品几十块,自制的话,也就一片Mega8的价

出0入0汤圆

发表于 2010-3-12 01:33:29 | 显示全部楼层
如果你连ALE,PSEN输出管脚的信号和频率都在斤斤计较,MONITOR-51这种用串口传输的半软件仿真方式,你也说可以用?

你以为MONITOR-51接到KEIL的HALT命令时,ALE和PSEN就不再输出了吗?


楼主的电路上有没有把ALE接到AD的时钟信号,这看一下电路就可以知道了,我在5楼也说过了,"如果对速度和容量没有要求"的前提下

我说的速度也包括外设(如ADC)的速度和时序,也没有说百分之百可以用AVR模拟,就像

003B: 90 80 02  MOV   DPTR,#8002H
003E:       E0  MOVX  A,@DPTR
003F: 30 E7 69  JNB   ACC.7,00ABH

这里8002H就是外设的地址,先不管是8255,8155,ADC芯片,M128一样有ALE和RD/WR,照接就对了,译码器自然会使能对应的片选

   LDI  XH,80H
   LDI  XL,02H

   LD   R16,X

   SBRS R16,7
   RJMP LOC00AB

以上为随手写写的(毕竟只是演示),如果对时序有要求,请自行在需要的地方加上NOP

至于PSEN,由于MEGA128内部的FLASH够大,可以把15K程序全放入片内,除非原设计者除了EEPROM外,PSEN另有接到别的地方,

否则就不用输出,这等看到原理图就知道了


“还有PSEN信号,指示单片机在读出ROM还是RAM的”这句就可以看出你对51还不是很熟

RAM和外设的读出和PSEN完全无关,它们是由RD/RW来使能的,当然也包括AD15-AD0

PSEN输出时,RD和WR是不会输出的

出0入0汤圆

发表于 2010-3-12 01:48:00 | 显示全部楼层
回复【51楼】kl818bc000 我不是马甲
-----------------------------------------------------------------------

8051好象只有130多个指令

出0入0汤圆

发表于 2010-3-12 02:00:30 | 显示全部楼层
如果加上不同的寻址方式模式,如MOV在指令表里只算一个指令,但是MOV A,#00和 MOV A,@R0和MOV A,@DPTR在模拟时

要当作三个指令,所以才有我说的几百个指令

出0入0汤圆

发表于 2010-3-12 07:04:00 | 显示全部楼层
回复【56楼】kl818bc000 我不是马甲
如果加上不同的寻址方式模式,如MOV在指令表里只算一个指令,但是MOV A,#00和 MOV A,@R0和MOV A,@DPTR在模拟时
要当作三个指令,所以才有我说的几百个指令
-----------------------------------------------------------------------

好像连把 MOV A,#00和 MOV A,@R0和MOV A,@DPTR 这些算三条指令 才能称得上100多条

出0入0汤圆

发表于 2010-3-12 08:16:14 | 显示全部楼层
在论坛里搜了一下,的确是只有100多条,谢谢提醒,我本来是认为一个字节的OP-CODE顶多256条指令

如果这样的话,要实现指令仿真的难度就更低了


以下转贴 http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=1705786&bbs_page_no=1&search_mode=1&search_text=51指令&bbs_id=1006

数据传送类指令                                 
MOV A,Rn        寄存器送累加器                        
MOV A,direct        直接字节送累加器                        
MOV A,@Ri        间接RAM送累加器                        
MOV A,#data        立即数送累加器                        
MOV Rn,A        累加器送寄存器                        
MOV Rn,direct        直接字节送寄存器                        
MOV Rn,#data        立即数送寄存器                        
MOV direct,A        累加器送直接字节                        
MOV direct,Rn        寄存器送直接字节                        
MOV direct2,direct1        直接字节送直接字节                        
MOV direct,@Ri        间接RAM送直接字节                        
MOV direct,#data        立即数送直接字节                        
MOV @Ri,A        累加器送间接RAM                        
MOV @Ri,direct        直接字节送间接RAM                        
MOV @Ri,#data        立即数送间接RAM                        
MOV DPTR,# data16        16位立即数送数据指针                        
MOVC A,@A+DPTR        以DPTR为变址寻址的程序存储器读操作                        
MOVC A,@A+PC        以PC为变址寻址的程序存储器读操作                        
MOVX A,@Ri        外部RAM(8位地址)读操作                        
MOVX A,@ DPTR        外部RAM(16位地址)读操作                        
MOVX @Ri,A         外部RAM(8位地址)写操作                        
MOVX @ DPTR,A        外部RAM(16位地址)写操作                        
PUSH direct        直接字节进栈                        
POP direct        直接字节出栈                        
XCH A,Rn        交换累加器和寄存器                        
XCH A,direct        交换累加器和直接字节                        
XCH A,@Ri        交换累加器和间接RAM                        
XCHD A,@Ri        交换累加器和间接RAM的低4位                        
算术运算指令                                 
ADD A,Rn        寄存器加到累加器                        
ADD A,direct        直接字节加到累加器                        
ADD A,@Ri        间接RAM加到累加器                        
ADD A,#data        立即数加到累加器                        
ADDC A,Rn        寄存器带进位加到累加器                        
ADDC A,direct        直接字节带进位加到累加器                        
ADDC A,@Ri        间接RAM带进位加到累加器                        
ADDC A,#data        立即数带进位加到累加器                        
SUBB A,Rn        累加器带寄存器                        
SUBB A,direct        累加器带借位减去直接字节                        
SUBB A,@Ri        累加器带借位减去间接RAM                          
SUBB A,#data        累加器带借位减去立即数                        
INC  A        累加器加1                        
INC  Rn        寄存器加1                        
INC  direct        直接字节加1                        
INC  @Ri        间接RAM加1                        
DEC  A        累加器减1                        
DEC  Rn        寄存器减1                          
DEC  direct        直接字节减1                        
DEC  @Ri        间接RAM减1                          
INC  DPTR        数据指针加1                        
MUL  AB        A乘以B                        
DIV  AB        A除以B                        
DA  A        十进制调整                        
逻辑运算                                 
ANL  A,Rn        寄存器“与”累加器                        
ANL  A,direct        直接字节“与”累加器                        
ANL  A,@Ri        间接RAM“与”累加器                        
ANL  A,#data        立即数“与”累加器                        
ANL  direct,A        累加器“与” 直接字节                        
ANL  direct,#data        立即数“与” 直接字节                        
ORL  A,Rn        寄存器“或”累加器                        
ORL  A,direct        直接字节“或”累加器                        
ORL  A,@Ri        间接RAM“或”累加器                        
ORL  A,#data        立即数“或”累加器                        
ORL  direct,A        累加器“或” 直接字节                        
ORL  direct,#data        立即数“或” 直接字节                        
XRL  A,Rn        寄存器“异或”累加器                        
XRL  A,direct        直接字节“异或”累加器                        
XRL  A,@Ri        间接RAM“异或”累加器                        
XRL  A,#data        立即数“异或”累加器                        
XRL  direct,A        累加器“异或” 直接字节                        
XRL  direct,#data        立即数“异或” 直接字节                        
CLR  A        累加器清零                        
CPL  A        累加器取反                        
移位操作                                 
RL  A        循环左移                        
RLC  A        带进位循环左移                        
RR  A        循环右移                        
RRC  A        带进位循环右移                        
SWAP  A        半字节交换                        
位操作指令                                 
MOV  C,bit        直接位送进位位                        
MOV  bit,C        进位位送直接位                        
CLR  C        进位位清零                        
CLR  bit        直接位清零                        
SETB  C        进位位置1                        
SETB  bit        直接位置1                        
CPL  C        进位位取反                        
CPL  bit        直接位取反                        
ANL  C,bit        直接位“与”进位位                        
ANL  C,/bit        直接位取反“与”进位位                        
ORL  C,bit        直接位“与”进位位                        
ORL  C,/bit        直接位取反“与”进位位                        
控制转移指令                                 
ACALL  addr11        绝对子程序调用                        
LCALL  addr16        长子程序调用                        
RET        子程序返回                        
RETI        中断返回                        
AJMP  addr11        绝对转移                        
LJMP  addr16        长转移                        
SJMP  rel         短转移                        
JMP  @A+DPTR        间接转移                        
JZ  rel        累加器为零转移                        
JNZ  rel        累加器不为零转移                        
CJNE A,direct,rel        直接字节与累加器比较,不相等则转移                        
CJNE A,#data,rel        立即数与累加器比较,不相等则转移                        
CJNE Rn,#data,rel        立即数与寄存器比较,不相等则转移                        
CJNE @Rn,#data,rel        立即数与间接RAM比较,不相等则转移                        
DJNZ  Rn,rel        寄存器减1不为零转移                        
DJNZ  direct,rel        直接字节减1不为零转移                        
NOP        空操作                        
JC  rel        进位位为1转移                        
JNC  rel        进位位为0转移                        
JB  bit,rel        直接位为1转移                        
JNB  bit,rel        直接位为0转移                        
JBC  rel        直接位为1转移并清零该位

出0入0汤圆

发表于 2010-3-12 08:20:46 | 显示全部楼层
简易仿真器硬件的作法:

####

为了不挡人X路,恕自删

####

简易仿真器软件的作法:

####

  理由同上,楼主若没看到,可以留下邮箱,发过去给你

####

出0入0汤圆

发表于 2010-3-12 10:48:46 | 显示全部楼层
【54楼】 kl818bc000 我不是马甲

   你大概不知道,51还可以在RAM里运行程序吧?他RAM和ROM的地址可以连在一起的.

  你要解决的,不是几个指令,你要解决的是一个系统到另一个系统,并且两个系统还要等效.

出0入0汤圆

发表于 2010-3-12 11:46:12 | 显示全部楼层
kl818bc000 我不是马甲

  我不准备再讨论这个问题了,我所以不占同你的方案,是因为你只是一个构想,而我在十年前确是实践过的,没模仿的东西是一个电解槽的控制器,只有16条指令,运行速度是32.768KHz,8个IO口,我用12M的51模拟的.
这是当年的代码,里面X5045,和162LCD的操作,还可以看看.
# pragma SYMBOLS,CODE,DEBUG,ot(4)
# include <absacc.h>
# include <reg52.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <intrins.h>

# define p1 P1^0
# define p2 P1^1
# define p3 P1^2
# define p4 P1^3
# define p5 P1^4
# define p6 P1^5
# define p7 P1^6
# define p8 P1^7

# define p10 P3^0
# define p11 P3^1
# define p12 P3^2
# define p13 P3^3
# define p14 P3^4
# define p15 P3^5
# define p16 P3^6
# define p17 P3^7

# define p21 P2^0
# define p22 P2^1
# define p23 P2^2
# define p24 P2^3
# define p25 P2^4
# define p26 P2^5
# define p27 P2^6
# define p28 P2^7

# define p32 P0^7
# define p33 P0^6
# define p34 P0^5
# define p35 P0^4
# define p36 P0^3
# define p37 P0^2
# define p38 P0^1
# define p39 P0^0
# define PC pc+10
typedef union
{
  float f[4];
  long l[2];
  unsigned long ul[2];
  int i[4];
  unsigned int ui[4];
  char c[8];
  unsigned char uc[8];
} bftype;

bftype data acca,accb;

unsigned char data LcdScreen[16];
unsigned char idata printstr[17];
unsigned char data dsmsec,msec=0,dssec,sec=0,dsmin,min=0,dshou,hou=0;
unsigned char data kmsec,mmsec;
unsigned int data pc=0;
unsigned int data poppc[4];
unsigned char data stake=0;

void mys(unsigned char n);
void ys(unsigned char n,unsigned char m);
void run(void);
void delay (unsigned char s);
void cls(void);
void display (void);
void nop(void);

# define LCD P0
sbit RS = p26;
sbit RW = p27;
sbit E = p28;
sbit BG = p21;
  
sbit CLOCK = p22;
sbit D_IN  = p23;
sbit D_OUT = p24;
sbit _CS   = p25;

sbit CS=p12;
sbit SO=p13;
sbit SI=p13;
sbit SCK=p22;

sbit PL=p17;
sbit CP=p16;
sbit QH=p15;

sbit io1=p1;
sbit io2=p2;
sbit io3=p3;
sbit io4=p4;
sbit io5=p5;
sbit io6=p6;
sbit io7=p7;
sbit io8=p8;

unsigned char bdata  ac;
sbit ac0 = ac^0;
sbit ac1 = ac^1;
sbit ac2 = ac^2;
sbit ac3 = ac^3;
sbit ac4 = ac^4;
sbit ac5 = ac^5;
sbit ac6 = ac^6;
sbit ac7 = ac^7;

unsigned char bdata ab;
sbit ab0 = ab^0;
sbit ab1 = ab^1;
sbit ab2 = ab^2;
sbit ab3 = ab^3;
sbit ab4 = ab^4;
sbit ab5 = ab^5;
sbit ab6 = ab^6;
sbit ab7 = ab^7;
bit showf=0;
# define WREN_INST 0X06
/* Write enable latch instruction (WREN)*/
# define WRDI_INST 0X04
/* Write disable latch instruction (WRDI)*/
# define WRSR_INST 0X01
/* Write status register instruction (WRSR)*/
# define RDSR_INST 0X05
/* Read status register instruction (RDSR)*/
# define WRITE_INST 0X02
/* Write memory instruction (WRITE)*/
# define READ_INST 0X03
/* Read memory instruction (READ)*/
# define BYTE_ADDR 0X55
/* Memory address for byte mode operations*/
# define BYTE_DATA 0X11
/*Data byte for byte write operation*/
# define PAGE_ADDR 0X1F
/* Memory address for page mode operations*/
# define PAGE_DATA1 0X22
/* 1st data byte for page write operation*/
# define PAGE_DATA2 0X33
/* 2nd data byte for page write operation*/
# define PAGE_DATA3 0X44
/* 3rd data byte for page write operation*/
# define DOG 0X00
# define NODOG 0X30
# define  MAX_POLL 0x99
/* Maximum number of polls*/
# define INIT_STATE 0x09
/* Initialization value for control ports*/
# define SLIC 0x30
/* Address location of SLIC*/

void wren_cmd(void);
void wrdi_cmd(void);
void wrsr_cmd(unsigned char aa);
unsigned char rdsr_cmd(void);
void byte_write(unsigned int,unsigned char);
unsigned char byte_read(unsigned int dd);
void page_write(unsigned char aa1,unsigned char aa2,unsigned char aa3,unsigned char aa4,unsigned int dd);
void sequ_read(void);
void rst_wdog(void);
void outbyt(unsigned char aa);
unsigned char inputbyt();
void wip_poll(void);

# define JT 0
# define DK 1
# define YS 2
# define ZY 3
# define SS 4
# define XS 5
# define JS 6
# define JIS 7
# define DZ 8
# define TZ 9
# define ZX 10
# define SDZ 11
# define DY 12
# define FH 13
# define JIESH 14
# define JSH 15
char code plen[16]={1,1,2,2,1,1,1,1,2,2,1,2,1,0,0,2};
char code help[16][8]={
";JT N   ",
";DK N   ",
";YS N,M ",
";ZY N,M ",
";SS N   ",
";XS N   ",
";JS N   ",
";JIS N  ",
";DZ N,M ",
";TZ N,M ",
";ZX N   ",
";SDZ N,M",
";DY N   ",
";FH     ",
";JIESH  ",
";JSH N,M"
};

void wren_cmd(void)
{
SCK=0;/* Bring SCK low */
CS=0;/* Bring /CS low */
outbyt(WREN_INST); /* Send WREN instruction */
SCK=0;/* Bring SCK low */
CS=1;/* Bring /CS high */
}

void wrdi_cmd(void)
{
SCK=0;/* Bring SCK low */
CS=0;/* Bring /CS low */
outbyt(WRDI_INST);/* Send WRDI instruction */
SCK=0;/* Bring SCK low */
CS=1;/* Bring /CS high */
}

/*
void wrsr_cmd(unsigned char aa)
{
SCK=0;
CS=0;
outbyt(WRSR_INST) ;
outbyt(aa);
SCK=0;
CS=1;
wip_poll();
}
*/
unsigned char rdsr_cmd (void)
{
unsigned char aa;
SCK=0;
CS=0;
outbyt(RDSR_INST);
aa=inputbyt();
SCK=0;
CS=1;
return aa;
}

void byte_write(unsigned int dd,unsigned char aa)
{
wren_cmd();
SCK=0;
CS=0;
outbyt( ((unsigned char)(dd>>5)&8) | WRITE_INST );
/* Send WRITE instruction including MSB of address */
outbyt((unsigned char)(dd));
outbyt(aa);
SCK=0;
CS=1;
wip_poll();
wrdi_cmd();
}

unsigned char byte_read(dd)
unsigned int dd;
{
unsigned char cc;
SCK=0;
CS=0;
outbyt( ((unsigned char)(dd>>5)&8) | READ_INST);
/* Send READ_INST instruction including MSB of address */
outbyt((unsigned char)(dd));
cc=inputbyt();
SCK=0;
CS=1;
return cc;
}


/*
void rst_wdog (void)
{
CS=0;
CS=1;
}
*/
void wip_poll(void)
{
unsigned char aa;
unsigned char my_flag;
for (aa=0;aa<MAX_POLL;aa++)
{
  my_flag=rdsr_cmd();
  if ((my_flag&0x01)==0)
     break;
}
}

void outbyt(unsigned char aa)
{
unsigned char i;
for (i=0;i<8;i++)
{
   SCK=0;
   SI=(bit)(aa&0x80);
   aa<<=1;
   SCK=1;
}
SI=0;
}

unsigned char inputbyt(void)
{
unsigned char aa=0;
char i;
SO=1;
for (i=0;i<8;i++)
{
   SCK=0;
   aa<<=1;
   if (SO) aa|=1;
   SCK=1;
}
return aa;
}

unsigned int getad(unsigned char port)
{
unsigned int data ad,i;
unsigned char data al=0,ah=0;

CLOCK=0;
_CS=0;
port<<=4;
for (i=0;i<4;i++)
{
D_IN=(bit)(port&0x80);CLOCK=1;CLOCK=0;
port<<=1;
}
       
for (i=0;i<6;i++)
{
CLOCK=1;CLOCK=0;
}

_CS=1;_nop_();_nop_();_CS=0;

for (i=0;i<2;i++)
{
D_OUT=1;
CLOCK=1;
ah<<=1;
if (D_OUT) ah|=0x01;
CLOCK=0;
}       

for (i=0;i<8;i++)
{
D_OUT=1;
CLOCK=1;
al<<=1;
if (D_OUT) al|=0x01;
CLOCK=0;
}       

_CS=1;

ad=(unsigned int)ah;
ad<<=8;
ad|=al;
return (ad);
}

void int0 (void) interrupt 0
{
}

void time_0 (void) interrupt 1
  {
   TL0=-50000%256;
   TH0=-50000/256;
   msec++;
   if (dsmsec>0) dsmsec--;
   if (kmsec>0) kmsec--;
   if (mmsec>0) mmsec--;
   if (msec==10)
     {msec=0;
     sec++;
     if (dssec>0) dssec--;
     if (sec==60)     
        {sec=0;
         min++;
         if (dsmin>0) dsmin--;
         if (min==60)
            {min=0;
             hou++;
             if (hou==60)
                {hou=0;
                if (dshou>0) dshou--;
                }
             }
        }  
     }
}

void WriteLcdCommand (unsigned char command)
{
E=0;
RS=0;
RW=0;
E=1;
_nop_();
LCD = command;
_nop_();
E=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}      

void WLcdCommand (unsigned char command)
{
unsigned char bf;
pr11:
E=0;
RS=0;
RW=1;
_nop_();
LCD=0xff;
E=1;
_nop_();
_nop_();
bf=LCD;
_nop_();
E=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if ((bf & 0x80)==0x80) goto pr11;
WriteLcdCommand (command);
}      

void WLcdData (unsigned char Data)
{
unsigned char bf;
pr11:
E=0;
RS=0;
RW=1;
_nop_();
LCD=0xff;
E=1;
_nop_();
_nop_();
bf=LCD;
_nop_();
E=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if ((bf & 0x80)==0x80) goto pr11;
E=0;
RS=1;
RW=0;
E=1;
_nop_();
LCD = Data;
_nop_();
E=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}


void Initialize(void)
{
TL0=0xb0;
TH0=0x3c;
TMOD=0x21;
TL0=-50000%256;
TH0=-50000/256;
PT0=0;
TR0 = 1;                 /* start timer 0 */
ET0 = 1;                 /* enable timer 0 interrupt */
EA=1;

  WriteLcdCommand(0x30);
  delay(0);
  WriteLcdCommand(0x30);
  delay(0);
  WriteLcdCommand(0x30);
  delay(0);

  WLcdCommand(0x38);  
  WLcdCommand(0x01);
  WLcdCommand(0x06);
  WLcdCommand(0x0C);
  cls();
}

void delay (unsigned char s)
   {unsigned char i,j;
     for(i=0;i<s;i++)
        for(j=0;j<255;j++);
   }

void display (void)
{
unsigned char i;
WLcdCommand(0x80);
for(i=0;i<8;i++)
  WLcdData(LcdScreen);
WLcdCommand(0xC0);
for(i=8;i<16;i++)
  WLcdData(LcdScreen);
}

void cls(void)
{
unsigned char i;
for(i=0;i<16;i++)
LcdScreen=' ';
display();
}

void showchar(unsigned char index,unsigned char a)
{
LcdScreen[index+0]=a/100+'0';
LcdScreen[index+1]=(a%100)/10+'0';  
LcdScreen[index+2]=(a%10)+'0';
}

void showint(unsigned char index,unsigned int a)
  {
  LcdScreen[index+0]=a/10000+'0';
  LcdScreen[index+1]=(a%10000)/1000+'0';
  LcdScreen[index+2]=(a%1000)/100+'0';
  LcdScreen[index+3]=(a%100)/10+'0';
  LcdScreen[index+4]=(a%10)+'0';
  }

void showadd(unsigned char index,unsigned int a)
  {
//  LcdScreen[index+0]=a/10000+'0';
  LcdScreen[index+0]=(a%10000)/1000+'0';
  LcdScreen[index+1]=(a%1000)/100+'0';
  LcdScreen[index+2]=(a%100)/10+'0';
  LcdScreen[index+3]=(a%10)+'0';
  }
void jt (unsigned char n)
{
switch (n){
  case 0:
   io1=0;
   break;
  case 1:
   io2=0;
   break;
  case 2:
   io3=0;
   break;
  case 3:
   io4=0;
   break;
  case 4:
   io5=0;
   break;
  case 5:
   io6=0;
   break;
  case 6:
   io7=0;
   break;
  case 7:
   io8=0;
   break;
   }
}   
void exjt(void)
{
  pc++;
  jt(byte_read(PC));
  pc++;
}


void dk (unsigned char n)
{
switch (n){
  case 0:
   io1=1;
   break;
  case 1:
   io2=1;
   break;
  case 2:
   io3=1;
   break;
  case 3:
   io4=1;
   break;
  case 4:
   io5=1;
   break;
  case 5:
   io6=1;
   break;
  case 6:
   io7=1;
   break;
  case 7:
   io8=1;
   break;
   }
}   
void exdk(void)
{pc++;
  dk(byte_read(PC));
  pc++;
}

void zy(unsigned int hl)
{
if (hl)
{
T2MOD = 0xfe;
C_T2=0;
CP_RL2=0;
RCAP2L=hl%256;
RCAP2H=hl/256;
TR2=1;
}
else
TR2=0;
}

void exzy(void)
{unsigned char ch;
  pc++;
  ch=byte_read(PC);
  switch(ch)
  {
   case 0:
    zy(0);
    break;
  case 1:
   zy(54069);  
   break;
  case 2:
   zy(55320);  
   break;
  case 3:
   zy(56435);  
   break;
  case 4:
   zy(56945);  
   break;
  case 5:
   zy(57883);  
   break;
  case 6:
   zy(58718);  
   break;
  case 7:
   zy(59462);  
   break;
  case 11:
   zy(59803);  
   break;
  case 12:
   zy(60428);  
   break;
  case 13:
   zy(60985);  
   break;
  case 14:
   zy(61241);  
   break;
  case 15:
   zy(61709);  
   break;
  case 16:
   zy(62127);  
   break;
  case 17:
   zy(62499);  
   break;
  case 21:
   zy(62671);  
   break;
  case 22:
   zy(62965);  
   break;
  case 23:
   zy(63261);  
   break;
  case 24:
   zy(63388);  
   break;
  case 25:
   zy(63623);  
   break;
  case 26:
   zy(63831);  
   break;
  case 27:
   zy(54017);  
   break;
   }
   pc++;
   ch=byte_read(PC);
   switch (ch)
   {
    case 0:
     mys(1);
     zy(0);
     break;
    case 1:
     mys(2);
     zy(0);
     break;
    case 2:
     mys(3);
     zy(0);
     break;
    case 3:
     mys(4);
     zy(0);
     break;
    case 4:
     mys(6);
     zy(0);
     break;
    case 5:
     mys(8);
     zy(0);
     break;
    case 6:
     mys(16);
     zy(0);
     break;
    case 7:
     mys(24);
     zy(0);
     break;
    case 8:
     mys(32);
     zy(0);
     break;
    case 9:
     mys(64);
     zy(0);
     break;
    case 10:
     break;
    case 11:
     zy(0);
     break;
   }
pc++;
}      
   
void mys(unsigned char n)
{mmsec=n;
  for(;;)
   if (mmsec==0) break;
}

void ys(unsigned char n,unsigned char m)
{
  switch (m){
  case 0:
   dsmsec=n;
   break;
  case 1:
   dssec=n;
   break;
  case 2:
   dsmin=n;
   break;
  case 3:
   dshou=n;
   break;
   }
  switch (m){
  case 0:
   for(;;)
     if (dsmsec==0) break;
   break;
  case 1:
   for(;;)
     if (dssec==0) break;
   break;
  case 2:
   for(;;)
     if (dsmin==0) break;
   break;
  case 3:
   for (;;)
     if (dshou==0) break;
   break;
   }
}

void exys(void)
{
  unsigned char ch;
  pc++;
  ch=byte_read(PC);
  pc++;
  ys(ch,byte_read(PC));
  pc++;
  }

void xs (unsigned char n)
  {
    showf=(bit)n;
  }
void exxs(void)
{
  pc++;
  xs(byte_read(PC));
  pc++;
}

void ss (unsigned char n)
{
acca.uc[0]=n;
if (showf)
    showchar(7,acca.uc[0]);   
    display();
}

void exss(void)
{
  pc++;
  ss(byte_read(PC));
  pc++;
}
void js(unsigned char n)
{
acca.uc[0]=acca.uc[0]+n;
if (showf)
    showchar(7,acca.uc[0]);   
    display();
}

void exjs(void)
{pc++;
  js(byte_read(PC));
  pc++;
  }

void jis(unsigned char n)
{
acca.uc[0]=acca.uc[0]-n;
if (showf)
    showchar(7,acca.uc[0]);   
    display();
}

void exjis(void)
{pc++;
  jis(byte_read(PC));
  pc++;
  }


unsigned char in(void)
  {
  unsigned int key=0;
  unsigned char i;
  PL=0;
  PL=1;
  for (i=0;i<16;i++)
    {
    key<<=1;
    QH=1;
    if (QH) key|=0x01;
    CP=0;
    CP=1;
    }
  switch (key)
  {
  case 65503:
  return 1;
  break;
  case 65471:
  return 2;
  break;
  case 57343:
  return 3;
  break;
  case 49151:
  return 4;
  break;
  case 65531:
  return 5;
  break;
  case 65534:
  return 6;
  break;
  case 64511:
  return 7;
  break;
  case 65279:
  return 8;
  break;
  case 65519:
  return 9;
  break;
  case 65407:
  return 10;
  break;
  case 61439:
  return 11;
  break;
  case 32767:
  return 12;
  break;
  case 65527:
  return 13;
  break;
  case 65533:
  return 14;
  break;
  case 63487:
  return 15;
  break;
  case 65023:
  return 16;
  break;
  case 57247:
  return 17;
  break;
  }  
  return 0;
  }

unsigned char readkey(void)
{unsigned char ch,ch2;
rep:
  ch=in();
  kmsec=1;
  for(;kmsec!=0;);
  ch2=in();
  if (ch!=ch2) goto rep;
  switch (ch)
  {
  case 13:
  return '1';
  break;
  case 14:
  return '2';
  break;
  case 15:
  return '3';
  break;
  case 16:
  return '4';
  break;
  case 9:
  return '5';
  break;
  case 10:
  return '6';
  break;
  case 11:
  return '7';
  break;
  case 12:
  return '8';
  break;
  case 5:
  return '9';
  break;
  case 6:
  return '0';
  break;
  case 7:
  return '.';
  break;
  case 8:
  return '-';
  break;
  case 1:
  return 'D';
  break;
  case 2:
  return 'I';
  break;
  case 3:
  return 'P';
  break;
  case 4:
  return 'N';
  break;
  }
return 0;
}

unsigned char waitkey()
{ unsigned char ch;
   for(;;)
     {ch=readkey();
      if (ch)
      break;
      }
   kmsec=5;
   for(;kmsec!=0;)
     if (readkey()==0) break;
   return ch;
  }

void gcprint(char x)
{
char i,ch;
for (i=0;i<17;i++)
  {
  ch=printstr;
  if (ch==0) break;
  LcdScreen[x+i]=ch;
  }
display();
}

void getstr(char x,char len)
   {
   char strp=0;
   unsigned char ch;
   for (strp=0;strp<len;strp++)
   printstr[strp]='_';
   printstr[strp]=0;
   gcprint(x);
   strp=0;
   for (;;)
   {
    ch=waitkey();
    if (ch=='D')
     {if (strp>0 && printstr[strp]=='_') strp--;
      printstr[strp]='_';
     }     
      else
      {
      if (ch=='I')
        {if (printstr[strp]!='_') strp++;
         printstr[strp]=0;
         break;}
         else
          {
           printstr[strp]=ch;
           if (strp<len-1) strp++;
          }
      }
   gcprint(x);
    }
}

char getc(char x,char len)
{
  getstr(x,len);
  return (char)atoi(printstr);
}

int geti(char x,char len)
{
  getstr(x,len);
  return atoi(printstr);
}

float getf(char x,char len)
{
  getstr(x,len);
  return atof(printstr);
}

void showhelp(unsigned char ass)
{
  unsigned char i,ch;
  for (i=8;i<16;i++)
  LcdScreen=' ';
if (ass<16)
{
   for (i=8;i<16;i++)
    {LcdScreen=help[ass][i-8];
    }
  }
else
{
LcdScreen[8]=';';
LcdScreen[10]='(';
LcdScreen[11]=ass;
LcdScreen[12]=')';
}
}

void writecomm(void)
{
unsigned char ch,chl;
ch=getc(5,3);
chl=plen[ch];
byte_write(PC,ch);   
pc++;
for(;;)
{
if (chl==0) break;
  cls();
  showadd(0,pc);
  ch=getc(5,3);
  byte_write(PC,ch);
  pc++;   
  chl--;
}
}

void showmem(void)
{
char ch;
pc=0;
for(;;)
  {
   showadd(0,pc);
   ch=byte_read(PC);
   showchar(5,ch);
   showhelp(ch);
   display();
   ch=waitkey();
   switch(ch)
    {
    case 'P':
    if (pc>0) pc--;
    break;
    case 'N':
    if (pc<502) pc++;
    break;
    case '.':
    writecomm();
    break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
     pc=geti(0,4);
     break;
    case '-':
     run();   
     break;
    }
  }
}

void exzx(void)
{
pc++;
pc=byte_read(PC);
}

void exdz(void)
{
unsigned char ch;
pc++;
ch=byte_read(PC);
switch (ch)
  {
  case 0:
    if (io1)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 1:
    if (io2)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 2:
    if (io3)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 3:
    if (io4)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 4:
    if (io5)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 5:
    if (io6)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 6:
    if (io7)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 7:
    if (io8)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
  case 8:
    if (dsmsec!=0 || dssec!=0 ||dsmin!=0||dshou!=0)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
  case 9:
  case 10:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  case 16:
  case 17:
  case 18:
  case 19:
  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
     if (in()!=(ch-8))
      {   
      pc++;
      pc=byte_read(PC);
      return;
      }
     break;
  }
pc++;
pc++;
return;
}

void extz(void)
{
unsigned char ch;
pc++;
ch=byte_read(PC);
switch (ch)
  {
  case 0:
    if (!io1)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 1:
    if (!io2)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 2:
    if (!io3)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 3:
    if (!io4)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 4:
    if (!io5)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 5:
    if (!io6)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 6:
    if (!io7)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
      
  case 7:
    if (!io8)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
  case 8:
    if (dsmsec==0 && dssec==0 && dsmin==0 && dshou==0)
      {
      pc++;
      pc=byte_read(PC);
      return;
      }
      break;
  case 9:
  case 10:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  case 16:
  case 17:
  case 18:
  case 19:
  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
     if (in()==(ch-8))
      {   
      pc++;
      pc=byte_read(PC);
      return;
      }
     break;
  }
pc++;
pc++;
return;
}

void exsdz(void)
{
  unsigned char ch;
  pc++;
  ch=byte_read(PC);
  if (acca.uc[0]==ch)
   {
   pc++;
   pc=byte_read(PC);
   return;
   }
pc++;
pc++;
  }

void exdy(void)
{
pc++;
poppc[stake]=pc+1;
stake++;
pc=byte_read(PC);
return;
}

void exfh(void)
{
stake--;
pc=poppc[stake];
return;
}

void exjsh(void)
{unsigned char ch;
pc++;
ch=byte_read(PC);
pc++;
switch( byte_read(PC))
{
  case 0:
   dsmsec=ch;
   break;
  case 1:
   dssec=ch;
   break;
  case 2:
   dsmin=ch;
   break;
  case 3:
   dshou=ch;
   break;
   }
pc++;
}
void run()
{unsigned char ch;
  cls();
  pc=0;
  for (;;)
   {
           ch=in();
            if (ch==17) return;
           ch=byte_read(PC);
    switch(ch){
    case JT:
     exjt();
     break;
    case DK:
     exdk();
     break;
    case YS:
     exys();
     break;
    case ZY:
     exzy();
     break;
    case SS:
     exss();
     break;
    case XS:
     exxs();
     break;
    case JS:
     exjs();
     break;
    case JIS:
     exjis();
     break;
    case DZ:
     exdz();
     break;
    case TZ:
     extz();
     break;
    case ZX:
     exzx();
     break;
    case SDZ:
     exsdz();
     break;   
    case DY:
     exdy();
     break;   
    case FH:
     exfh();
     break;   
    case JIESH:
     return;
     break;
    case  JSH:
     exjsh();
     break;
    }
  }
}

void main()
{
delay(0);
Initialize();
cls();
for (;;)
{
//showint(0,in());
//display();
  showmem();
}
}

出0入0汤圆

发表于 2010-3-12 12:19:17 | 显示全部楼层
回复【49楼】kl818bc000  我不是马甲
##########################################
   硬件作法请看下面59楼介绍
##########################################
速度快的可以模拟速度慢的,容量大的可以模拟容量小的,如果速度真有问题,把转成的AVR汇编后面加几个NOP就成了
工控产品一般都是事件(如中断,外设,输入)驱动的,也都会留一定的余量,除非是用来模拟类似USB这类严格的时序,一般都可以
这个方法和硬件仿真器一样可以马上在原来板子上电验证,软件仿真就作不到
但也可以马上重新画板,把已经读懂的硬件用AVR内的存储外设取代(如ROM,RAM,ADC,8255..),作成产品上市销售,这就是硬件仿真器作不到的
除非楼主的老板只要楼主读懂程序,不想生产出产品来盈利,不过那是不可能的
当然,用C8051这类增强型51也行,只是开发环境和仿真工具不像AVR/STM32选择那么多又便宜
-----------------------------------------------------------------------

C8051的JTAG只要100块钱,也算是便宜了的吧?

出0入0汤圆

发表于 2010-3-12 13:53:05 | 显示全部楼层
回复【62楼】lollipop 天堂里没有猪头猪脑

除了仿真器,开发环境也是很重要,还有,出了问题有没有很多地方可以找到协助

我是综合了以上考虑,站在开发者的立场给楼主提了建议

我推荐在国内主流的芯片,我也捞不到任何好处


最后,芯片供货和价格也是个大问题,这就交给楼主的老板去决定

出0入0汤圆

发表于 2010-3-12 16:22:40 | 显示全部楼层
回复【60楼】zhxzhx 一丁
【54楼】 kl818bc000 我不是马甲
   你大概不知道,51还可以在RAM里运行程序吧?他RAM和ROM的地址可以连在一起的.
  你要解决的,不是几个指令,你要解决的是一个系统到另一个系统,并且两个系统还要等效.

回复【61楼】 zhxzhx 一丁
  我不准备再讨论这个问题了,我所以不占同你的方案,是因为你只是一个构想,而我在十年前确是实践过的,
没模仿的东西是一个电解槽的控制器,只有16条指令,运行速度是32.768KHz,8个IO口,我用12M的51模拟的.

-----------------------------------------------------------------------

你没看到我在【54楼】有写

"除非原设计者除了EEPROM外,PSEN另有接到别的地方,否则就不用输出,这等看到原理图就知道了"

我有说过PSEN只能接ROM的片选吗? 或不能接到外部RAM吗?

或许楼主的板上除了8155的256字节RAM以外,根本没有别的外部RAM

还在讨论 "51还可以在RAM里运行程序" , 有意义吗?

等楼主的原理图出来就知道了,现在没什么好争的


我早就在6楼说过 "如果对速度和容量没有要求" 的前提下,是可以这样作, 也没说百分之百可以作

但你几乎斩钉截铁的说我这只是不切实际的构想,一定行不通的,还找来一堆几乎不可能出现的极端问题

来驳斥我的想法,还动不动说:

"这你就老外了" "你大概不知道" "看来你没有用过" "很怀疑你干没干过这种活"

"纸上谈兵,根本没有实际经验" "你模拟个屁" "月薪1万的工程师"...

等我一一把你的质疑解答,并把我的软硬件的作法都公开后,甚至把你不知道"PSEN时不会输出RD"的事实都告诉你,

一句道歉或感谢的话也没有,有必要这样吗?


让我不知道,我到底是挡到你推销产品?还是我叫别人不要在用8051了,妨碍了你接51的项目赚钱?


楼主也是,丢了问题出来,人却不知道跑那去了,我下星期要出差,也没时间再回贴,我就到此打住

出0入0汤圆

发表于 2010-3-12 16:49:02 | 显示全部楼层
全是牛人

出0入0汤圆

 楼主| 发表于 2010-3-12 20:08:06 | 显示全部楼层
大家要和气,和气生财啊。
我也不知道老板的下一步意图的。
因为这个东西挺大的,我前面说过,有机器没原理图,还不知道老板愿意不愿意我们花时间弄出原理图呢。
我来和一把稀泥。
反正论坛嘛,大家讨论讨论,主要目的还是能扩大点思路,不为当前,也为以后万一用上了,对吧。
谢谢各位啊。
祝大家植树节快乐

出0入0汤圆

发表于 2010-3-13 11:58:47 | 显示全部楼层
看反汇编程序是要有耐心的,我就弄过pic单片机的花了大约半年,要有硬件电路才好理解原作者的意图,之所以愿意花大量时间来读解是为了在原先的基础上进行改进。

出0入0汤圆

发表于 2010-3-13 12:18:35 | 显示全部楼层
呵呵,看样子是八十年代、九十年代初的东西。

通过反汇编来分析算法,或修改程序,是那个时期搞技术人的主要工作。

分析算法,其目标是反演出程序流程图。

有了算法,用什么芯片,那就不是问题了。

出0入0汤圆

发表于 2010-3-13 13:31:18 | 显示全部楼层
看42楼的代码,倾向于源代码就是汇编语言写成的,挺简洁的,c编译器出来的东西应该比这个乱

出0入8汤圆

发表于 2010-3-13 15:28:04 | 显示全部楼层
我们老师写过13000行的汇编,编译下来40k的程序。。。

出0入0汤圆

发表于 2011-4-27 23:04:13 | 显示全部楼层
018F:    7B 03  MOV   R3,#03H
0191:    7C 00  MOV   R4,#00H
0193:    7D 08  MOV   R5,#08H
0195:    7E 00  MOV   R6,#00H
0197:    7F 00  MOV   R7,#00H
0199:    A8 04  MOV   R0,04H
019B: 12 01 3E  LCALL 013EH
019E:       2E  ADD   A,R6
019F:       FE  MOV   R6,A
01A0:       E4  CLR   A
01A1:       3F  ADDC  A,R7
01A2:       FF  MOV   R7,A
01A3:    A8 05  MOV   R0,05H
01A5:       08  INC   R0
01A6:    D8 FE  DJNZ  R0,$
01A8:    DD EF  DJNZ  R5,0199H
01AA:    78 03  MOV   R0,#03H
01AC:       C3  CLR   C
01AD:       EF  MOV   A,R7
01AE:       13  RRC   A
01AF:       FF  MOV   R7,A
01B0:       EE  MOV   A,R6
01B1:       13  RRC   A
01B2:       FE  MOV   R6,A
01B3:    D8 F7  DJNZ  R0,01ACH
01B5:       E4  CLR   A
01B6:       3E  ADDC  A,R6
01B7:       FE  MOV   R6,A
01B8:       EC  MOV   A,R4
01B9:    24 41  ADD   A,#41H
01BB:       F8  MOV   R0,A
01BC:       EE  MOV   A,R6
01BD:       26  ADD   A,@R0
01BE:       13  RRC   A
01BF:    34 00  ADDC  A,#00H
01C1:       F6  MOV   @R0,A
01C2:       0C  INC   R4
01C3:    DB CE  DJNZ  R3,0193H
01C5: 12 01 7F  LCALL 017FH
01C8:       22  RET
这个很像是2进制转10进制的程序

出0入0汤圆

发表于 2011-4-27 23:15:40 | 显示全部楼层
我用51的时候都是用汇编的,那时板子都是用洞洞板自己飞线焊的,还要像电脑主板一样做了几个插槽,需要的时候就做一些外设插在上面,很好玩的,不过现在放弃51都比较长时间了,如果年轻15年的话我也可以帮一帮手.

出0入0汤圆

发表于 2011-4-27 23:21:01 | 显示全部楼层
其中LCALL 013EH 是读数的过程
LCALL 017FH
则是要转换出来的数难道是显示的
017F: 85 42 3E  MOV   3EH,42H
0182: 85 43 3F  MOV   3FH,43H
0185: D5 3C 06  DJNZ  3CH,018EH
0188: 75 3C 18  MOV   3CH,#18H
018B: 85 41 3D  MOV   3DH,41H
018E:       22  RET

出0入0汤圆

发表于 2011-6-28 09:44:47 | 显示全部楼层
我现在写了一个汇编程序 全部大概是8000行 其中4000行是LCD现实数据,程序大小50K 其实汇编一个一个功能分清楚 然后调用执行 觉得 不怎么难!!但我只懂汇编  实在是没办法@!!

出0入0汤圆

发表于 2011-6-28 10:59:03 | 显示全部楼层
呵呵,我开始用51时,也是先用汇编的。建议最好是先把原理图搞出来,再根据原理图来分析程序,不然..........

记得几年前晚上天天研究一个项目,汇编大概2W多行,烧写文件有63点多K,64k的单片机刚刚好!唉,体力活呀!呵呵

出50入10汤圆

发表于 2011-6-28 11:44:01 | 显示全部楼层
一切皆有可能,楼主搞定没有?

出0入0汤圆

发表于 2011-6-28 14:12:11 | 显示全部楼层
当年电子六所的前辈们,据说是把DOS反汇编了,一行行地啃下来的,然后才弄出了CCDOS。

出0入0汤圆

发表于 2011-11-17 00:01:02 | 显示全部楼层
谁可以搞定。我也找你。我的比较多,700多k。

出0入0汤圆

发表于 2011-11-17 00:10:22 | 显示全部楼层
这个,,,不难,就是得有耐心,,,
我用汇编在window上写过一个带窗口的程序,不过那个程序没有5000行

出0入0汤圆

发表于 2011-11-17 11:21:41 | 显示全部楼层
哇 说不定自己重新来写或许更快一些......

出0入0汤圆

发表于 2011-11-20 14:36:38 | 显示全部楼层
回复【36楼】zhxzhx  一丁
-----------------------------------------------------------------------

显然是二分枚举答案 具体就懒得看了。。。

出0入0汤圆

发表于 2015-3-12 17:32:46 | 显示全部楼层
不知道进展如何,搞汇编我很拿手,我离南京也挺近。

出0入0汤圆

发表于 2015-3-12 17:44:21 | 显示全部楼层
楼上啊,这是四年五年前的。。。。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 10:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表