打印

HotC51汇编数组宏V1.09开始全面支持C51函数

[复制链接]
1589|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
HotC51|  楼主 | 2009-3-10 22:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*----------------------------------------------------------------------------
        HotC51宏汇编数组定义头文件(hotmacro.h V1.09)
最初建立时间: 2009.2.18 
最近修改时间: 2009.3.10
增  添原  因: 为全面支持裸奔式实时操作系统HotTask51做准备
              hotmacro.h宣告“宏C”计划开始, 
              支持Keil C51带参数输入输出的"汇编数组之过程与函数"。
              HotC51使用宏汇编数组可以方便地与Keil C51“通讯”
应        用: 可以用COM接口技术对HotC51汇编数组进行封装
            macro_Function_Arg3 (CRCR8, macro_U8_arg1, macro_U8_arg2, macro_U8_arg3)
            {
            #define CRCR8_LOOP -15
            #define CRCR8_NEXT size_XRL_A_Rn()
                asm_MOV_B(8),//设置8位计数器
            //CRCR8_LOOP:
                asm_MOV_A_Rn(macro_U8_arg3),//取明文
                asm_XRL_A_Rn(macro_U8_arg1),//异或初值
                asm_RRC_A(),//右移CRC8一位,注意ACC.0移入CY
                asm_MOV_A_Rn(macro_U8_arg1),//再取初值
                asm_JNC(CRCR8_NEXT),//CY为0不异或权,跳过下句
                asm_XRL_A_Rn(macro_U8_arg2),//异或权
            //CRC8R_NEXT:
                asm_RRC_A(),//将CY移入ACC.7
                asm_MOV_Rn_A(macro_U8_arg1),//保存本次结果
                asm_MOV_A_Rn(macro_U8_arg3),//再取明文
                asm_RR_A(),//准备下一位
                asm_MOV_Rn_A(macro_U8_arg3),//保存明文,注意已改变
                asm_DJNZ_B(CRCR8_LOOP),//未完继续到CRCR8_LOOP
                macro_return(),
            };
未  来计  划: 首先将HotC51汇编数组做成比宏汇编更好用的接近C习惯.
              逐步完善,最终全面到达“宏C”之目标。
菜农HotPower@126.com 2008.3.10 18:58 于西安大雁塔村农会
-----------------------------------------------------------------------------*/

#include "hotwc3.h"
/*-----------------------------------------------------------------------
        函数CRCR8(macro_U8_arg1, macro_U8_arg2, macro_U8_arg3)
入口:
        macro_U8_arg1 初值
        macro_U8_arg2 权
        macro_U8_arg3 明文
出口:
        macro_U8_Result CRCR8结果
-----------------------------------------------------------------------*/
macro_Function_Arg3 (CRCR8, macro_U8_arg1, macro_U8_arg2, macro_U8_arg3)
{
#define CRCR8_LOOP -15
#define CRCR8_NEXT size_XRL_A_Rn()
    asm_MOV_B(8),//设置8位计数器
//CRCR8_LOOP:
    asm_MOV_A_Rn(macro_U8_arg3),//取明文
    asm_XRL_A_Rn(macro_U8_arg1),//异或初值
    asm_RRC_A(),//右移CRC8一位,注意ACC.0移入CY
    asm_MOV_A_Rn(macro_U8_arg1),//再取初值
    asm_JNC(CRCR8_NEXT),//CY为0不异或权,跳过下句
    asm_XRL_A_Rn(macro_U8_arg2),//异或权
//CRC8R_NEXT:
    asm_RRC_A(),//将CY移入ACC.7
    asm_MOV_Rn_A(macro_U8_arg1),//保存本次结果
    asm_MOV_A_Rn(macro_U8_arg3),//再取明文
    asm_RR_A(),//准备下一位
    asm_MOV_Rn_A(macro_U8_arg3),//保存明文,注意已改变
    asm_DJNZ_B(CRCR8_LOOP),//未完继续到CRCR8_LOOP
/*---------------------------------------------
//将初值安排在Arg1可节省下面2句
    asm_MOV_A_Rn(macro_U8_arg1),//取结果
    asm_MOV_Rn_A(macro_U8_Result),//送返回值
----------------------------------------------*/
    macro_return(),
};


/*-----------------------------------------------------------------------
        函数CRCL8(macro_U8_arg1, macro_U8_arg2, macro_U8_arg3)
入口:
        macro_U8_arg1 初值
        macro_U8_arg2 权
        macro_U8_arg3 明文
出口:
        macro_U8_Result CRCR8结果
-----------------------------------------------------------------------*/
macro_Function_Arg3 (CRCL8, macro_U8_arg1, macro_U8_arg2, macro_U8_arg3)
{
#define CRCL8_LOOP -15
#define CRCL8_NEXT size_XRL_A_Rn()
    asm_MOV_B(8),//设置8位计数器
//CRCL8_LOOP:
    asm_MOV_A_Rn(macro_U8_arg3),//取明文
    asm_XRL_A_Rn(macro_U8_arg1),//异或初值
    asm_RLC_A(),//左移CRC8一位,注意ACC.7移入CY
    asm_MOV_A_Rn(macro_U8_arg1),//再取初值
    asm_JNC(CRCL8_NEXT),//CY为0不异或权,跳过下句
    asm_XRL_A_Rn(macro_U8_arg2),//异或权
//CRC8R_NEXT:
    asm_RLC_A(),//将CY移入ACC.0
    asm_MOV_Rn_A(macro_U8_arg1),//保存本次结果
    asm_MOV_A_Rn(macro_U8_arg3),//再取明文
    asm_RL_A(),//准备下一位
    asm_MOV_Rn_A(macro_U8_arg3),//保存明文,注意已改变
    asm_DJNZ_B(CRCL8_LOOP),//未完继续到CRCL8_LOOP
/*---------------------------------------------
//将初值安排在Arg1可节省下面2句
    asm_MOV_A_Rn(macro_U8_arg1),//取结果
    asm_MOV_Rn_A(macro_U8_Result),//送返回值
----------------------------------------------*/
    macro_return(),
};


/*-----------------------------------------------------------------------
        函数Week(macro_U16_arg1, macro_U8_arg2, macro_U8_arg3)
入口:
        macro_U16_arg1 年(0x00~0x9999)BCD码
        macro_U8_arg2  月(0x01~0x12)BCD码
        macro_U8_arg3  日(0x01~0x31)BCD码
出口:
        macro_U8_Result 星期(0~6)
-----------------------------------------------------------------------*/
macro_Function_Arg3 (Week, macro_U16_arg1, macro_U8_arg2, macro_U8_arg3)
{
#define Week_LOOP -20
    asm_MOV_R1(4),//将百年、年、月、日的BCD码换成二进制数
//Week_LOOP:
    asm_MOV_A(0x4f),//DataBuffer偏移,程序长度
//分别取出macro_U16H_arg1,macro_U16L_arg1macro_U8_arg2, macro_U8_arg3
    asm_MOVC_A_aDPTR(),
    asm_MOV_R0_A(),
    asm_MOV_A_iR0(),
    asm_ANL_A(0x0f),
    asm_XCH_A_iR0(),
    asm_SWAP_A(),
    asm_ANL_A(0x0f),
    asm_MOV_B(10),
    asm_MUL_AB(),
    asm_ADD_A_iR0(),
    asm_MOV_iR0_A(),
    asm_INC_DPTR(),
    asm_DJNZ_R1(Week_LOOP),//四次未完继续
//(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7,特别注意1月2月的年为"去年"
    asm_CJNE_Rn(macro_U8_arg2, 0x03, 0),//判断月
    asm_JNC(size_MOV_A_Rn() + size_ORL_A() + size_MOV_Rn_A()             + size_DEC_Rn() + size_CJNE_Rn() + size_DEC_Rn()),//月
//月<=2
    asm_MOV_A_Rn(macro_U8_arg2),
    asm_ORL_A(0x04),//1月2月同5月六月表
    asm_MOV_Rn_A(macro_U8_arg2),
    asm_DEC_Rn(macro_U16L_arg1),//1月2月的年为"去年"
    asm_CJNE_Rn(macro_U16L_arg1, 0xff, size_DEC_Rn()),//Week_Start
    asm_DEC_Rn(macro_U16H_arg1),
//Week_Start:
//百年%4*5
    asm_MOV_A_Rn(macro_U16H_arg1),//百年
    asm_ANL_A(0x03),
    asm_MOV_Rn_A(macro_U16H_arg1),//百年%4
    asm_CLR_C(),
    asm_RLC_A(),
    asm_CLR_C(),
    asm_RLC_A(),//百年%4*4
    asm_ORL_A_Rn(macro_U16H_arg1),//百年%4*5
    asm_MOV_Rn_A(macro_U16H_arg1),//保存(百年%4*5),最大值3*5=15
//年+年/4
    asm_MOV_A_Rn(macro_U16L_arg1),//年
    asm_CLR_C(),
    asm_RRC_A(),
    asm_CLR_C(),
    asm_RRC_A(),
    asm_ADD_A_Rn(macro_U16L_arg1),//年+年/4
    asm_MOV_Rn_A(macro_U16L_arg1),//保存(年+年/4),最大值99+25=124
    asm_MOV_A_Rn(macro_U8_arg2),//月
    asm_MOV_B(13),
    asm_MUL_AB(),//13*月->A
    asm_MOV_B(8),
    asm_ADD_A_B(),//13*月+8
    asm_MOV_B(5),
    asm_DIV_AB(),//(13*月+8)/5 商->A
    asm_MOV_Rn_A(macro_U8_arg2),//保存((13*月+8)/5)最大值33
//日
    asm_ADD_A_Rn(macro_U8_arg3),//日,最大值31
    asm_ADDC_A_Rn(macro_U16H_arg1),//(百年%4*5),最大值15
    asm_ADDC_A_Rn(macro_U16L_arg1),//(年+年/4),最大值99+25=124
/*
此时ACC最大为15+124+33+31=203,
注意,蔡勒公式内无203.-2*C可能会越界,菜农给出的蔡勒公式完整表述:
W = (203+C/4-2*C+Y+Y/4+(13*M+8)/5+D)%7
菜农星期公式:
W = (    C%4*5+Y+Y/4+(13*M+8)/5+D)%7
*/
    asm_MOV_B(7),//取余数%7
    asm_DIV_AB(),
    asm_XCH_A_B(),
    asm_MOV_Rn_A(macro_U8_Result),//送返回值(星期)
    macro_return(),
//数据区DataBuffer
    asm_DB(macro_U16H_arg1),
    asm_DB(macro_U16L_arg1),
    asm_DB(macro_U8_arg2),
    asm_DB(macro_U8_arg3)
};

code const IHotWc3Com_Interface wc3Function =//物理分配的COM接口
{
    (unsigned char (*)(unsigned char arg1, unsigned char arg2, unsigned char arg3))CRCR8,
    (unsigned char (*)(unsigned char arg1, unsigned char arg2, unsigned char arg3))CRCL8,
    (unsigned char (*)(unsigned int arg1, unsigned char arg2, unsigned char arg3))Week,
};

/*--------------------------------------------
         定义COM接口
--------------------------------------------*/
//com函数指针表
interface 
{
    unsigned char (*CRCR8)(unsigned char arg1, unsigned char arg2, unsigned char arg3);
    unsigned char (*CRCL8)(unsigned char arg1, unsigned char arg2, unsigned char arg3);
    unsigned char (*Week)(unsigned int arg1, unsigned char arg2, unsigned char arg3);
}IHotWc3Com_Vtbl_Interface, *pIHotWc3Com_Vtbl_Interface;

//com函数调用的com接口
interface
{
    const IHotWc3Com_Vtbl_Interface Vtbl;//com函数指针表
}IHotWc3Com_Interface, *pIHotWc3Com_Interface;


void main()
{
unsigned char crcr8, crcl8;
unsigned char week;
//HotC51汇编数组宏全面支持带参数输入输出的"数组函数"
    crcr8 = wc3Function.Vtbl.CRCR8(0, 0x18, 0xff);//初值,权, 明文
    crcl8 = wc3Function.Vtbl.CRCL8(0, 0x18, 0x01);//初值,权, 明文
    week  = wc3Function.Vtbl.Week(0x2009, 0x03, 0x10);//2009年3月10日的BCD码
//................................
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

306

帖子

0

粉丝