📄 startup.a51
字号:
;-------------------------------------------------------------------------------
; Copyright (c) Raisonance S.A. 1989 - 2003
; This is the 'C' language "STARTUP" routine for RC51
;
; File name: STARTUP.A51
;
; Purpose: To provide the initial starting code for the 8051 from
; power-up to the initial execution of the main() routine.
;
; Scope: This file contains all the code and information required
; to accomplish "Purpose". It is applicable to all memory
; models and initialization concepts EXCEPT the "Tiny"
; model. This file, assembled in the appropriate memory model,
; is automatically linked in by the linker when it encounters
; a "main" symbol in the object modules to be linked.
;
; The routine will be executed each time the controller
; experiences a "power-on" condition.
;
; If you wish to use this startup routine with your assembly
; code too, you should add a "main" label in your code.
;
; Considerations: The values selected are intended for a standard 8051 controller.
; In most cases these will work well for must other processors
; under most conditions. The ranges for initialization, or the
; initialization values can be changed or modified as needed.
;
; Other micros: The most common change to this module will be to accommodate
; the Philips '751 chips with their restricted internal memory
; space, and the lack of LJMP or LCALL instructions. The
; locations in this module that may need changing are marked
; with: (** For 751 use **)
;
; Caveats: It is possible to modify this file and effect the execution
; the target processor in many ways. Often settings and
; selections have effects on each other. Some many not be
; compatible. This startup routine is provided "as is". If
; you change it to meet some design objective you are responsible
; to know the outcome of your selections, and their effect upon
; the target system.
;
;-------------------------------------------------------------------------------
; NOTE: YOU SHOULD ALTER THIS FILE ONLY AFTER YOU HAVE BUILT AND TESTED YOUR
; CODE, AND YOU'RE CONVINCED THAT YOU CAN MAKE IT RUN OR WORK BETTER BY DOING
; SO. IF YOU ONLY NEED SOME SPECIFIC INITIALIZATIONS, IT IS RECOMMENDED THAT
; YOU DO THEM IN THE FIRST FEW LINES OF YOUR MAIN() ROUTINE. MODIFY THIS FILE
; ONLY AS A LAST RESORT.
;-------------------------------------------------------------------------------
$include( upsd3300.inc ) ; uPSD3300 Assembly Equates
EXTRN IDATA ( _STACK )
EXTRN CODE ( main ) ; main routine called at the end of this startup.
EXTRN DATA ( HPD_ADDR ) ; HPD_ADDR is supposed to be P2 address...
EXTRN NUMBER ( _INITP2? ) ; Initial value for P2
;-------------------------------------------------------------------------------
; The next section contains the starting address and length of each of the data
; segments. Note that you must use these labels given below, as Raisonance 51
; toolchain understands them and uses them to modify actual values in the module.
;
; The IDATA information and setup:
; Initialize the values for the IDATA space. By default IDATA starts at
; location 0, and goes to top of internal memory. On the 8051 that's 128 bytes
; (0x7F), on other derivatives it may be up to 256 bytes (0xFF). On some it can
; be as little as 64 bytes. Since it will always start at location 0x0000, we
; will permit the linker to manage this variable.
; NOTE: IDATA space physically overlaps both the DATA, REGISTER, and BIT spaces.
; At a very minimum, the user is admonished to initialize at least the first 8
; bytes (Register bank 0) and at least one additional byte for the stack.
IDATASTART EQU 000h ; a default value and is added only for completeness.
IDATALEN EQU 0FFh ; typical length is 256 bytes.
;
; (** For 751 use **) you may need to adjust the IDATALEN value
;
; Note: The entire internal address space is IDATA space! The lower
; 128 bytes is also DATA space. Both DATA and IDATA physically
; overlap the BIT area. So initializing either of these spaces
; will initialize the BIT area as well. Given the nature of the
; 8051 DATA space initializations are best done as IDATA accesses.
;
; The PDATA information and setup:
; Since PDATA resides in XDATA space it is included for reference only. Note that
; you must use (and correctly initialize) P2 in order to succeed with PDATA accesses.
; The value for P2 is in PAGES of 256 bytes, and is dependent upon the address
; selected for that page.
PDATASTART EQU 000h ; this is the default value.
PDATALEN EQU 000h ; typical length is 256 bytes.
;
; The XDATA information and setup:
; If your application has non-standard address ranges for XDATA this is where you
; will need to alter the values. The length and location of XDATA space can vary
; according to the chip and/or hardware design. If reentrant functions are used,
; this space should be initialized. But this is entirely dependent upon system
; and program design requirements. By default, XDATA space IS NOT initialized.
; To force initialization you should make the XDATA length value non-zero.
XDATASTART EQU 000h ; the start address of XDATA space
XDATALEN EQU 000h ; typically we don't need to initialize xdata space
; ANSI 'C' language specification requires initialization of global and static
; variables. This is done at the end of this startup. However, if for any reason
; you do not want this initialization, turn INIDATA to zero.
;-------------------------------------------------------------------------------
;
; Advanced details:
; To initialize static and global variables, RC51 generates a partial segment
; with the name ?C_INITSEGSTART. The contents of this segment are:
; (nb = number of bytes)
; 0 - nb * 4 + bit 0 if in data memory
; + bit 1 if in xdata memory
; + bit 2 if zero initialization
; Note: if bit 0 and bit 1 of nb are zero, it is a bit initialization
; else we are in a data, idata or xdata initialization
; 1 - Low byte of address to initialize
; 2 - High byte of address to initialize
; 3 - data (limited to 127 bytes)
;
; LX51 chains the partial segments into the final segment, and adds a NULL
; termination.
;
;-------------------------------------------------------------------------------
INIDATA EQU 001h ; allow global and static variable initialization.
;
; This selection permits or denies the initialization of chip I/O registers. By
; default, I/O initialization is OFF. On critical programs eliminating this step
; can save a few bytes of code. Typically chip I/O is initialized early in the
; MAIN() routine. To do this initialization in this startup routine, make the
; variable non-zero. You may insert additional initialization requirements into
; the code section controlled by this directive. For instance, you could put
; initialization of a watchdog timer into this section.
INITIO EQU 001h ; make non-zero to permit I/O initialization
TIM1_INIT EQU 0E8h ; timer 1 initialization value for 9600 baud
;-------------------------------------------------------------------------------
; Watch dog timer macro:
; In some instances when many initializations are performed it may be necessary
; to service the watch dog timer. The actual code needed to accomplish this
; will be dependent upon the actual device in use, and it's operating
; characteristics. This is a template for such a watch dog timer function.
PET_THE_DOG MACRO
; Enter your watchdog service code here.
ENDM
;
; To use this macro, place it into the code stream at the location where it may
; need to be called.
;-------------------------------------------------------------------------------
; The next section contains the EXTERNAL stack initialization directive.
XSTACK EQU 000h ; make non-zero to use external stack
XSTACKLEN SET 000h ; an initial length for the external stack
;-------------------------------------------------------------------------------
; Miscellaneous directives.
INTERNAL_XRAM_LIKE_8xC592 EQU 000h ; make non-zero to use internal XRAM.
;===============================================================================
; Startup relocatable CODE segment name is set here.
?PR?C51_STARTUP? SEGMENT CODE
NAME STARTUP
;-----------------------------------------------------
; Debug IRQ vector (only needed when using trace mode)
; DO NOT MODIFY
;-----------------------------------------------------
CSEG AT 063H ; debug interrupt vector
nop ; Leave this 3 byte sequence
nop ; it is used by RIDE debugger
RETI
;-------------------------------------------------------------------------------
; By design, all code for the 8051 MUST start at location 0000h. In special cases
; it is desirable to change this location. For instance, to make a monitor
; resident at location 8000h. When you do this other considerations are required.
; For instance, the location of interrupts must be considered.
;
; 1. Set the CODE segment defined above to begin at location 0x0000. To change
; the location of where you want your startup vector to be located you would
; modify this value. Note: That there are considerations beyond just simple
; code locations if you do this. Consequently this action is NOT RECOMMENDED!
CSEG AT 0000h
;-------------------------------------------------------------------------------
; 2. Make the label public and jump to it. This permits the vector to live at
; the CSEG location defined above, and the rest of the code to be relocated
; as required by the linker to resolve it's instructions and directives.
PUBLIC ?C_START
LJMP ?C_START ;(** For 751 use **) you must change the LJMP to an AJMP
;-------------------------------------------------------------------------------
; 3. Set the C51_STARTUP segment to be relocatable
; Define LX51 Start up Macro Area that inits MCU
RSEG ?PR?C51_STARTUP?
?C_START:
;>>>>>>LX51_STARTUP_MICRO_SPECIFIC
;NOTE - Ride will add and remove initialization code here.
;DO NOT EDIT this block of code!
; Call external "C" Function to init uPSD device in file upsd_init.c
EXTRN CODE (upsd_Init)
MOV SP, #_STACK ; Setup SP (linker defines location)
CALL upsd_Init ; Call C function to init uPSD
;<<<<<<LX51_STARTUP_MICRO_SPECIFIC
;-------------------------------------------------------------------------------
; 4. Stack definition and initialization:
; The "STACK" is not actually defined anywhere. It is always located in IDATA
; space. It is always only 1 byte long. And it always GROWS UP. The stack has
; been given the name, "_STACK". This location, by name, will be adjusted by the
; linker to be located on top of all internal memory (registers+DATA+BITS+IDATA)
; consumed.
MOV SP, #_STACK
;-------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -