📄 start12.c
字号:
LDY 2,X+ //装载目的地址
#endif //FAR_DATA
#if defined(__HCS12X__) && defined(FAR_DATA)
#if defined(__OPTIMIZE_FOR_SIZE__) // -os, 默认
Copy: PSHA
LDAA 1,X+
GSTAA 1,Y+ //从ROM中移出一个字节数据到数据域
PULA
__FEED_COP_IN_HLI() //如果有必要就喂COP
DBNE D,Copy //复制字节的循环
#else
LSRD //除以2并且保存位0到标志Carry中
BEQ Copy1 //我们复制了多于一个字节吗?
Copy: PSHD
LDD 2,X+
GSTD 2,Y+ //从ROM中移出一个字数据到数据域
PULD
__FEED_COP_IN_HLI() //如果有必要就喂COP
DBNE D,Copy //复制字的循环
Copy1:
BCC NextBlock //处理最后一个字节?
LDAA 1,X+
GSTAA 1,Y+ //从ROM中移出一个字节数据到数据域
#endif
#elif defined(__OPTIMIZE_FOR_SIZE__) // -os, 默认
Copy: MOVB 1,X+,1,Y+ //从ROM中移出一个字节数据到数据域
__FEED_COP_IN_HLI() //如果有必要就喂COP
DBNE D,Copy //复制字节的循环
#else //__OPTIMIZE_FOR_TIME__
LSRD //除以2并且保存位0到标志Carry中
BEQ Copy1 //我们复制了多于一个字节吗?
Copy: MOVW 2,X+,2,Y+ //从ROM中移出一个字数据到数据域
__FEED_COP_IN_HLI() //如果有必要就喂COP
DBNE D,Copy //复制字的循环
Copy1:
BCC NextBlock //处理最后一个字节
MOVB 1,X+,1,Y+ //复制最后一个字节
#endif //__OPTIMIZE_FOR_SIZE__/__OPTIMIZE_FOR_TIME__
BRA NextBlock
funcInits: //在C++需要的时候调用全局构造函数
#if defined(__cplusplus)
#if defined(__ELF_OBJECT_FILE_FORMAT__)
#if defined( __BANKED__) || defined(__LARGE__)
LDY _startupData.nofInitBodies//装载cpp的数量
BEQ done //如果cppcount == 0, 跳转到 done
LDX _startupData.initBodies //装载第一个模块的地址来初始化
nextInit:
LEAX 3,X //进行下一个模块的初始化
PSHX //保存下一个功能函数的地址来初始化
PSHY //保存cpp计数器
CALL [-3,X] //使用双重间接调用来装载页寄存器
PULY //恢复cpp计数器
PULX //恢复实际地址
DEY //cpp计数器自减
BNE nextInit
#else //defined( __BANKED__) || defined(__LARGE__)
LDD _startupData.nofInitBodies//装载cpp的数量
BEQ done //如果cppcount == 0, 跳转到 done
LDX _startupData.initBodies //装载第一个模块的地址来初始化
nextInit:
LDY 2,X+ //装载第一个模块的地址来初始化
PSHD
PSHX //保存实际地址
JSR 0,Y //调用初始化函数
PULX //恢复实际地址
PULD //恢复cpp计数器
DBNE D, nextInit
#endif //defined( __BANKED__) || defined(__LARGE__)
#else //__ELF_OBJECT_FILE_FORMAT__
LDX _startupData.mInits //装载第一个模块的地址来初始化
#if defined( __BANKED__) || defined(__LARGE__)
nextInit: LDY 3,X+ //装载初始化函数的地址
BEQ done //当地址 == 0时停止
//在通常情况下这个功能函数的偏移地址为非0,
//因此可以不需要进行这个测试
#ifdef __InitFunctionsMayHaveOffset0__
BRCLR -1,X, done, 0xff //当地址 == 0时停止
#endif //__InitFunctionsMayHaveOffset0__
PSHX //保存下一个功能函数的地址来初始化
CALL [-3,X] //使用双重间接调用来装载页寄存器
#else //defined( __BANKED__) || defined(__LARGE__)
nextInit:
LDY 2,X+ //装载第一个模块的地址来初始化
BEQ done //停止当函数地址 == 0
PSHX //保存实际地址
JSR 0,Y //调用初始化函数
#endif //defined( __BANKED__) || defined(__LARGE__)
PULX //恢复实际地址
BRA nextInit
#endif //__ELF_OBJECT_FILE_FORMAT__
done:
#endif //__cplusplus
}
}
#endif //__ONLY_INIT_SP
//调用主函数不支持返回任何值
#if defined( __ELF_OBJECT_FILE_FORMAT__) && defined(__cplusplus ) && 0
#if !defined(FAR_DATA) && (defined( __BANKED__) || defined(__LARGE__))
static void __far Fini(void)
#else
static void Fini(void)
#endif
{
// 目的: 1) 在C++中调用全局构造
__asm {
#if defined( __BANKED__) || defined(__LARGE__)
LDY _startupData.nofFiniBodies//装载cpp的数量
BEQ done //如果cppcount == 0, 跳转到done
LDX _startupData.finiBodies //装载第一个模块地址来完成操作
nextInit2:
LEAX 3,X //增加下一个init
PSHX //保存下一个功能函数的地址来完成操作
PSHY //保存cpp计数器
CALL [-3,X] //使用双重间接调用来装载页寄存器
PULY //恢复cpp计数器
PULX //恢复实际地址
DEY //cpp计数器自减
BNE nextInit2
#else //defined( __BANKED__) || defined(__LARGE__)
LDD _startupData.nofFiniBodies//装载cpp的数量
BEQ done //如果cppcount == 0, 跳转done
LDX _startupData.finiBodies //装载第一个模块地址来完成操作
nextInit2:
LDY 2,X+ //装载第一个模块地址来完成操作
PSHD
PSHX //保存实际地址
JSR 0,Y //调用完成的功能函数
PULX //恢复实际地址
PULD //恢复cpp计数器
DBNE D, nextInit2
#endif //defined(__BANKED__) || defined(__LARGE__)
done:;
}
}
#endif
#include "non_bank.sgm"
#pragma MESSAGE DISABLE C12053 //在调试信息中,堆栈指针不会改变
#pragma NO_FRAME
#pragma NO_ENTRY
#if !defined(__SMALL__)
#pragma NO_EXIT
#endif
//_Startup函数必须被调用是为了初始化全局变量和来调用main函数
//你可以修改这个函数或者在你的启动代码中调用它来实现一个不同的启动功能
//你应该创建需要的IO寄存器作为WINDEF(仅HC12A4)或者COP寄存器来运行在硬件上
//为了设置复位中断,下面的几个方法是可能的:
//1.复位中断函数使用中断号0
//2.加以下的代码到你的prm文件:VECTOR ADDRESS 0xfffe _Startup
//当然,甚至有更多可能性存在
//复位中断必须设置为了让应用程序有一个定义的入口点
#if defined(__SET_RESET_VECTOR__)
__EXTERN_C void __interrupt 0 _Startup(void) {
#else
__EXTERN_C void _Startup(void) {
#endif
//目的: 1)初始化堆栈
// 2)初始化内存,复制初始化数据等等(初始化)
// 3)调用主函数:
//参数:无
//调用者:由连接器生成的预启动代码
// 或者由复位中断直接调用
//初始化堆栈指针
INIT_SP_FROM_STARTUP_DESC(); //HLI宏定义在hidef.h 中
#if defined(_HCS12_SERIALMON)
//为了支持EB386,需要监视在内存和EEPROM中的基本软件,
//这是通过编辑内存和EEPROM区域来实现的。
___INITRG = 0x00; // 锁定寄存器块在0x0000
___INITRM = 0x39; // 锁定RAM结束地址在0x3FFF
___INITEE = 0x09; // 锁定EEPROM结束地址在0x0fff
#endif
//这里用户定义代码可以被插入,堆栈能被使用
#if defined(_DO_DISABLE_COP_)
_DISABLE_COP();
#endif
//例子:设置WinDef寄存器来允许分配页
#ifdef HC812A4 //HC12 A4 需要WINDEF来配置哪些页面是可变的
#if (__ENABLE_EPAGE__ != 0 || __ENABLE_DPAGE__ != 0 \
|| __ENABLE_PPAGE__ != 0)
WINDEF= __ENABLE_EPAGE__ | __ENABLE_DPAGE__ | __ENABLE_PPAGE__;
#endif
#endif
#if defined(__DO_SET_MMCTL1__)
//设置MMCTL1字节。请使用HCS12XE并且根据你的配置改变相应的位
//注意:MMCTL1只能写一次因此请在这儿改写这些初始化
//这个应该在调用初始化之前被完成
#define _MMCTL1_ADR (0x00000013)
#define _MMCTL1_BIT_TGMRAMON (1<<7) //EEE Tag RAM and FTM SCRATCH RAM
//在内存中可见
#define _MMCTL1_BIT_EEEIFRON (1<<5) //EEE IFR在内存空间中可见
#define _MMCTL1_BIT_PGMIFRON (1<<4) //在内存空间中编写IFR可见
#define _MMCTL1_BIT_RAMHM (1<<3) //RAM仅在内存的高半块中
#define _MMCTL1_BIT_EROMON (1<<2) //使得内存中仿效的Flash或者ROM有效
#define _MMCTL1_BIT_ROMHM (1<<1) //Flash或者ROM仅在内存的高半块中
#define _MMCTL1_BIT_ROMON (1<<0) //使得Flash或者ROM在内存空间中有效
#define _MMCTL1_SET(value) ((*(volatile unsigned char*)_MMCTL1_ADR)=(value))
_MMCTL1_SET(_MMCTL1_BIT_ROMON | _MMCTL1_BIT_EROMON | _MMCTL1_BIT_RAMHM \
| _MMCTL1_BIT_ROMHM);
#endif
#ifndef __ONLY_INIT_SP
Init();
#endif
//这儿用户定义的代码能被插入,所有的全局变量已经被被初始化
#if defined(_DO_ENABLE_COP_)
_ENABLE_COP(1);
#endif
//调用main()
main();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -