//-------------------------------------------------------------------------*
// 文件名:  start08.c                                                      *
// 说  明:  68HC08标准启动文件                                             *
// 注  意:  这个版本的启动代码假定main没有返回值(在堆栈中保存_Startup函数的*
//          两个字节返回地址）                                             *
//-------------------------------------------------------------------------*

#define __NO_FLAGS_OFFSET   //在启动数据描述符中不需要标志域
#define __NO_MAIN_OFFSET    //在启动数据描述符中不需要main域

#include <start08.h>

#define __EXTERN_C

__EXTERN_C extern void main(void); //main函数原型

#include "non_bank.sgm"

/***************************************************************************/
/*宏定义规定了在启动代码中如何控制看门狗（COP）                            */
/*如果不进行宏定义，则启动代码中不对看门狗进行处理                         */               
/***************************************************************************/
#define __FEED_COP_IN_HLI()   //不做任何事情

#pragma DATA_SEG FAR _STARTUP
struct _tagStartup _startupData;    // 只读:_startupData在ROM中分配，由连接文件初始化

#pragma MESSAGE DISABLE C20001  // 警告 C20001: 堆栈指针的不同值依赖于控制流
//函数_COPY_L从堆栈释放一些固有的字节

//进行优化
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma NO_FRAME
static void near loadByte(void) {
  asm {
             PSHH
             PSHX
             LDHX    5,SP
             LDA     0,X
             AIX     #1
             STHX    5,SP
             PULX
             PULH
             RTS
      }
}


__EXTERN_C extern void _COPY_L(void);

#ifdef __ELF_OBJECT_FILE_FORMAT__
	#define toCopyDownBegOffs 0
#else
	#define toCopyDownBegOffs 2 
#endif

//-------------------------------------------------------------------------*
//函数名: Init                                                             *
//功  能:  1)将RAM中已分配数据的区域赋值为0                                *
//         2)初始化运行时数据,...                                          *
//         3)将初始化数据从ROM复制到RAM                                    *
//参  数: 无                                                               *
//返  回: 无                                                               *
//说  明: 对没有使用的标记不产生警告，这将在下面的HLI中使用                *
//-------------------------------------------------------------------------*
static void Init(void) {
  int i;
  int *far p;

  asm {
ZeroOut:
             LDA    _startupData.nofZeroOuts:1 ; // nofZeroOuts
             INCA
             STA    i:1                        ; // i is counter for number of zero outs
             LDA    _startupData.nofZeroOuts:0 ; // nofZeroOuts
             INCA
             STA    i:0
             LDHX   _startupData.pZeroOut      ; // *pZeroOut
             BRA    Zero_5
Zero_3:
             ; // CLR    i:1 is already 0
Zero_4:
             ; // { HX == _pZeroOut }
             PSHX
             PSHH
             ; // { nof bytes in (int)2,X }
             ; // { address in (int)0,X   }
             LDA    0,X
             PSHA
             LDA    2,X
             INCA
             STA    p                 ; // p:0 is used for high byte of byte counter
             LDA    3,X
             LDX    1,X
             PULH
             INCA
             BRA    Zero_0
Zero_1:
           ;  // CLRA   A is already 0, so we do not have to clear it
Zero_2:
             CLR    0,X
             AIX    #1
             __FEED_COP_IN_HLI()     	; // it's necessary to feed the COP in the inner loop for the fast COP timeout of some derivatives
Zero_0:
             DBNZA  Zero_2
Zero_6:
             DBNZ   p, Zero_1
             PULH
             PULX                     ; // restore *pZeroOut
             AIX    #4                ; // advance *pZeroOut
Zero_5:
             DBNZ   i:1, Zero_4
             DBNZ   i:0, Zero_3

CopyDown:

  }

  asm {
             LDHX   _startupData.toCopyDownBeg:toCopyDownBegOffs
             PSHX
             PSHH
Loop0:
             JSR    loadByte          ; // 加载高位计数器
             TAX                      ; // 比较并保存结果
             INCA
             STA    i
             JSR    loadByte          ; // 加载低字节计数器
             INCA
             STA    i:1
             DECA
             BNE    notfinished
             CBEQX  #0, finished
notfinished:

             JSR    loadByte          ; // load high byte ptr
             PSHA
             PULH
             JSR    loadByte          ; // load low byte ptr
             TAX                      ; // HX is now destination pointer
             BRA    Loop1
Loop3:
Loop2:
             __FEED_COP_IN_HLI()
             JSR    loadByte          ; // 加载数据字节
             STA    0,X
             AIX    #1
Loop1:
             DBNZ   i:1, Loop2
             DBNZ   i:0, Loop3
             BRA    Loop0

finished:
             AIS #2
    }
}
 
//-------------------------------------------------------------------------*
//函数名: _Startup                                                         *
//功  能:  1)初始化堆栈                                                    *
//         2)初始化运行时间,...                                            *
//           初始化RAM，复制初始数据等                                     *
//         3)调用main函数                                                  *
//参  数: 无                                                               *
//返  回: 无                                                               *
//说  明: (1)连接文件(Project.prm)中的语句：'VECTOR 0 _Startup'将复位向量设*
//           置为_Startup                                                  *
//        (2)从连接文件生成的代码'_PRESTART'处调用                         *
//-------------------------------------------------------------------------*
#pragma NO_EXIT
__EXTERN_C void _Startup(void)
{
    INIT_SP_FROM_STARTUP_DESC();
    __asm LDHX #0x0870; __asm TXS;
    Init();
    __asm JMP main;
}
