/**************************************************************************************************
  Filename:       chipcon_cstartup.s51
  Revised:        $Date: 2010-01-28 17:00:06 -0800 (Thu, 28 Jan 2010) $
  Revision:       $Revision: 21615 $

  Description:    Contains the code executed before the C/EC++ "main"
                  function is called. The code is designed to run on any
                  processor based on the 8051 architecture.


  Copyright 2005-2007 Texas Instruments Incorporated. All rights reserved.

  IMPORTANT: Your use of this Software is limited to those specific rights
  granted under the terms of a software license agreement between the user
  who downloaded the software, his/her employer (which must be your employer)
  and Texas Instruments Incorporated (the "License").  You may not use this
  Software unless you agree to abide by the terms of the License. The License
  limits your use, and you acknowledge, that the Software may not be modified,
  copied or distributed unless embedded on a Texas Instruments microcontroller
  or used solely and exclusively in conjunction with a Texas Instruments radio
  frequency transceiver, which is integrated into your product.  Other than for
  the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  works of, modify, distribute, perform, display or sell this Software and/or
  its documentation for any purpose.

  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
  INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, 
  NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

  Should you have any questions regarding your right to use this Software,
  contact Texas Instruments Incorporated at www.TI.com. 
**************************************************************************************************/

/******************************************************************************

Copyright 2004-2005 IAR Systems. All rights reserved.
Updated by Chipcon to not clear ?CBANK at init.

******************************************************************************/


#include "iar_common.h"

	PROGRAM	CSTARTUP
	PUBLIC  __program_start

	EXTERN  ?B0
	EXTERNS_FOR_ALL_DPTR_SYMBOLS()
	REQUIRE ?B0
   REQUIRE __call_main

#if (__NUMBER_OF_DPTRS__ > 1)
	REQUIRE ?RESET_DPS
#endif

#if (__CORE__ == __CORE_EXTENDED1__)
   REQUIRE __call_init_extended1
#endif

   ; Uncomment this when rom-monitor requires 3 NOPS between statements.
   ; REQUIRE ?ROM_MONITOR_NOPS

   RSEG	REGISTERS:NOROOT:DATA
   PUBLIC  ?REGISTERS

?REGISTERS:

//------------------------------------------------------------------------
// The C stack segment. Should be mapped into internal data RAM
//
//   ISTACK:    Should be mapped into internal data RAM
//   PSTACK:    Should be mapped into external data RAM page
//   XSTACK:    Should be mapped into external data RAM
//   EXT_STACK: Should be mapped into external data RAM
//
//------------------------------------------------------------------------
// The C stack is used for LCALL's and temporary storage for
// code generator help-routines (math etc). The stack will be
// located after all other internal RAM variables if the stan-
// dard linking procedure is followed. Note that C interrupt
// routines can double stack size demands.
//
//------------------------------------------------------------------------

   RSEG	ISTACK:NOROOT:IDATA
   PUBLIC  ?ISTACK_START
?ISTACK_START:

   RSEG	PSTACK:NOROOT:XDATA
   PUBLIC  ?PSTACK_START
?PSTACK_START:

   RSEG	XSTACK:NOROOT:XDATA
   PUBLIC  ?XSTACK_START
?XSTACK_START:

   RSEG	EXT_STACK:NOROOT:XDATA
   PUBLIC  ?EXT_STACK_START
?EXT_STACK_START:


//------------------------------------------------------------------------
//
// Define reset vector.
//
//------------------------------------------------------------------------

   COMMON   INTVEC:CODE:ROOT(0)

// The reset vector must be located at address zero, the reset
// vector is located first in the INTVEC segment. This segment
// must thus be located at address zero. Be carefull if using
// assembler sequences located with the ASEG directive, which may
// prevent the INTVEC segment from being located at address zero.

// Not enforcing location at address 0 for boot loader for OAD.
// LIMIT SFB(INTVEC),0,0,"The INTVEC segment must begin at address zero"

?reset_vector:
   DB	0x02    ; LJMP
#if defined(START_INIT_IN_FAR)
   DB	BYTE3(__program_start)
#endif
   DB	high(__program_start)
   DB	low(__program_start)


//------------------------------------------------------------------------
//					
// Initialize the chip to suit IAR ICC8051 Compiler
//
//------------------------------------------------------------------------

   RSEG    CSTART:CODE:ROOT
   EXTERN  ?REGISTER_BANK
   REQUIRE ?ISTACK_START
   REQUIRE ?REGISTERS
   REQUIRE ?reset_vector

__program_start:
   MOV     PSW,#(?REGISTER_BANK << 3)

//------------------------------------------------------------------------
//
// Reset of bank registers and stack pointers
// ==========================================
//
// ?RESET_SP:  Resets the IDATA stack pointer
// ?RESET_ESP: Resets the extended stack pointer
// ?RESET_PSP: Resets the PDATA stack pointer
// ?RESET_XSP: Resets the XDATA stack pointer
//
// ?RESET_CODE_BANK:      Resets the current code bank register
// ?RESET_PDATA_BANK:     Resets the high byte of PDATA page register
//
// ?RESET_DPS: Resets the DPTR selector (point at DPTR0)
//
//------------------------------------------------------------------------

//------------------------------------------------------------------------
//
// Reset idata or extended stack pointer
//   extended stack pointer if  the extended stack is used
//   otherwise, the ordinary stack pointer
//
//------------------------------------------------------------------------

#if (defined(__EXTENDED_STACK__) )

//
// Reset extended stack pointer
//

   PUBLIC  ?RESET_ESP
   REQUIRE ?EXT_STACK_START
   EXTERN	?ESP

?RESET_ESP:
   MOV     SP,#low(sfb(EXT_STACK))
   MOV     ?ESP,#high(sfb(EXT_STACK))
#else

//
// Reset idata stack pointer
//

   PUBLIC  ?RESET_SP
   REQUIRE ?ISTACK_START

?RESET_SP:
   MOV     SP,#SFB(ISTACK)
#endif


//------------------------------------------------------------------------
//
// Reset pdata stack pointer
//
//------------------------------------------------------------------------

   RSEG	CSTART:CODE:NOROOT
   PUBLIC  ?RESET_PSP
   EXTERN  ?PSP
   REQUIRE ?PSTACK_START
   REQUIRE ?RESET_PDATA_BANK
   EXTERN  ?PSTACK

?RESET_PSP:
   MOV     ?PSP,#low(sfe(PSTACK))


//------------------------------------------------------------------------
//
// Reset xdata stack pointer
//
//------------------------------------------------------------------------

   RSEG	CSTART:CODE:NOROOT
   PUBLIC  ?RESET_XSP
   EXTERN  ?XSP
   REQUIRE ?XSTACK_START
   EXTERN  ?XSTACK

?RESET_XSP:
   MOV     ?XSP,#low(sfe(XSTACK))
   MOV     ?XSP+1,#high(sfe(XSTACK))


//------------------------------------------------------------------------
//
// Reset code bank
//
//------------------------------------------------------------------------

#if ( (__CODE_MODEL__ == __CM_BANKED__) || ( __CODE_MODEL__ == __CM_NEAR__ ) )
   RSEG	CSTART:CODE:NOROOT
   PUBLIC  ?RESET_CODE_BANK
   EXTERN  ?CBANK

?RESET_CODE_BANK:
   NOP
//	MOV	?CBANK,#0x00
#endif


//------------------------------------------------------------------------
//
// Reset pdata page
//
//------------------------------------------------------------------------

   RSEG	CSTART:CODE:NOROOT
   PUBLIC  ?RESET_PDATA_BANK
   EXTERN  ?PBANK
   EXTERN	?PBANK_NUMBER

?RESET_PDATA_BANK:
   MOV     ?PBANK,#?PBANK_NUMBER
#if (defined ( __EXTENDED_DPTR__))
   EXTERN  ?PBANK_EXT

?RESET_PDATA_BANK_EXT:
   MOV     ?PBANK_EXT,#0x00
#endif


//------------------------------------------------------------------------
//
// Reset data pointer select register
//
//------------------------------------------------------------------------

#if (__NUMBER_OF_DPTRS__ > 1)

   RSEG	CSTART:CODE:NOROOT
   PUBLIC  ?RESET_DPS
   EXTERN  ?DPS

?RESET_DPS:
   MOV	?DPS,#0x00

#endif



//------------------------------------------------------------------------
//
// Initialize the extended1 core
//
//------------------------------------------------------------------------

#if (__CORE__ == __CORE_EXTENDED1__)

   REQUIRE __call_init_extended1

   RSEG	CSTART:CODE:NOROOT
   PUBLIC  __call_init_extended1
   EXTERN	__init_extended1


__call_init_extended1:
   DB	0x12    ; LCALL
#if defined(START_INIT_IN_FAR)
   DB	BYTE3(__init_extended1)
#endif
   DB	high(__init_extended1)
   DB	low(__init_extended1)
#endif



//------------------------------------------------------------------------
//
// Jump to the code that performs the rest of the system initialization
// before calling main().
//
//------------------------------------------------------------------------


   RSEG    CSTART:CODE:NOROOT
   EXTERN  ?cmain

__call_main:
   LJMP	?cmain

   ENDMOD

;----------------------------------------------------------------;
; Virtual registers						 ;
; =================						 ;
; Below is some segment needed for the IAR ICC C/EC++ compiler   ;
;								 ;
; BREG  : A segment for 8 bit registers for use by the compiler. ;
;         ?B0 is the first register.                             ;
; VREG  : Segement that holds up to 32 virtual registers for     ;
;         use by the compiler. ?V0 is the first register.        ;
; PSP   : Segment containing the PDATA stack pointer (?PSP)      ;
; XSP   : Segment containing the XDATA stack pointer (?XSP)      ;
; 								 ;
;----------------------------------------------------------------;
; NOTE: The XLINK varialbe _NR_OF_VIRTUAL_REGISTERS must be 	 ;
;       defined to set the size for the VREG segment.   	 ;
;----------------------------------------------------------------;

   MODULE  VIRTUAL_REGISTERS
   PUBLIC  ?B0
   PUBLIC  ?V0
   PUBLIC  ?PSP
   PUBLIC  ?XSP
   RSEG    BREG:BIT:NOROOT

?B0:
   DS      8

   RSEG    VREG:DATA:NOROOT
   EXTERN	_NR_OF_VIRTUAL_REGISTERS
?V0:
   DS      0

   RSEG    PSP:DATA:NOROOT
   EXTERN  ?RESET_PSP
   REQUIRE	?RESET_PSP
?PSP:
   DS      1

   RSEG    XSP:DATA:NOROOT
   EXTERN  ?RESET_XSP
   REQUIRE	?RESET_XSP
?XSP:
   DS      2

   ENDMOD ; VIRTUAL_REGISTERS


;----------------------------------------------------------------;
; Register banks						 ;
; =================						 ;
; Below is some segment needed for the IAR ICC C/EC++ compiler   ;
;								 ;
; The register banks will only be included if the #pragma        ;
; register_bank is used for the corresponding register bank      ;
; 								 ;
;----------------------------------------------------------------;

   MODULE	REGISTER_BANK0
   PUBLIC	__REG_BANK_0
   ASEGN	__REG_BANK0:DATA,0x00

__REG_BANK_0:
   DS	8
   ENDMOD


   MODULE	REGISTER_BANK1
   PUBLIC	__REG_BANK_1
   ASEGN	__REG_BANK1:DATA,0x08
__REG_BANK_1:
   DS	8
   ENDMOD


   MODULE	REGISTER_BANK2
   PUBLIC	__REG_BANK_2
   ASEGN	__REG_BANK2:DATA,0x10
__REG_BANK_2:
   DS	8
   ENDMOD


   MODULE	REGISTER_BANK3
   PUBLIC	__REG_BANK_3
   ASEGN	__REG_BANK3:DATA,0x18
__REG_BANK_3:
   DS	8
   ENDMOD	; REGISTER_BANK3

   END
