ARM Technical Support Knowledge Articles

LOCATING STARTUP ROUTINES IN ECODE

Applies to: A251 Macro Assembler

Answer


Information in this article applies to:


QUESTION

How do I locate the startup code in the ECODE memory class?

ANSWER

You must locate both the startup code and the initialization code in ECODE to do what you want. The easiest way to do that is to use the following START251.A51, INITEDAT.A51, and INITHDAT.A51 files in your project.

There are a few caveats that you must consider.

  1. The reset vector (at 0FF0000h) must contain an LJMP instead of an EJMP. This is because the first interrupt vector is located at 0FF0003h.
  2. The reset vector must jump to something in the CODE space (0FF0000h-0FFFFFFh) that performs an EJMP to the startup code in the 0FE0000h area.
  3. Interrupts will still vector to 0FF0003h. 0FF000Bh, 0FF0013h, and so on.

With these points in mind, here are the startup code files. Note that if you wish to receive these files via e-mail, see the Attached Files section below.

START251.A51

This file is required. It is the startup code that is executed immediately after reset.

$SET (ROMHUGE)
;------------------------------------------------------------------------------
;  This file is part of the C251 Compiler package
;  Copyright KEIL ELEKTRONIK GmbH 1995 - 1998
;------------------------------------------------------------------------------
;  START251.A51:  This code is executed after processor reset.
;
;  To translate this file use A251 with the following invocation:
;
;     A251 START251.A51  [ MODSRC ] [ SET (ROMHUGE) ]
;  whereby:
;     MODSRC         defines the 251 Source Mode  (default is Binary Mode)
;     SET (ROMHUGE)  defines the ROM (HUGE) Mode  (default is ROM(LARGE) )
;
;  To link the modified STARTUP.OBJ file to your application use the following
;  L251 invocation:
;
;     L251 START251.OBJ, <your object file list> <controls>
;
;------------------------------------------------------------------------------
;
;  251 Configuration Bytes Definition for off-chip (external) config bytes
;
$SET (CONFIGB = 0)   ; Set this variable if you want to set external config
;                    ; bytes at address FF:FFF8 and FF:FFF9.
;
; Wait State for PSEN#/RD#/WR# signal except region 01:xxxx (WSA1 & WSA0 Bits)
; WSA        Val  Description
; ---        ---  -----------
WSA  EQU 3  ; 3 = 0 wait state for all regions except region 01:xxxx
;           ; 2 = extended to 1 wait state  for all regions except 01:xxxx
;           ; 1 = extended to 2 wait states for all regions except 01:xxxx
;           ; 0 = extended to 3 wait states for all regions except 01:xxxx
;
; Extend ALE pulse
; XALE       Val  Description
; ----       ---  -----------
XALE EQU 1  ; 1 = ALE pulse is one TOSC
;           ; 0 = ALE pulse is three TOSC, this adds one external wait state
;
; RD# and PSEN# Function Select  (RD1 and RD0 Bits)
; RD         Val  RD Range   PSEN Range  P1.7 Func  Features
; --         ---  --------   ----------  ---------  --------
RDRG EQU 3  ; 3 = <=7F:FFFF  >=80:FFFF   P1.7/CEX4  Compatible with 8051
;           ; 2 = P3.7 only  All address P1.7/CEX4  One additional port pin
;           ; 1 = RD#=A16    All address P1.7/CEX4  128K External Address space
;           ; 0 = RD#=A16    All address P1.7=A17   256K External Address space
;
; Page Mode Select
; PAGE       Val  Description
; ----       ---  -----------
PAGM EQU 1  ; 1 = Non-page Mode (A15:8 on P2, A7:0/D7:0 on P0, 8051 compatible)
;           ; 0 = Page Mode (A15:8/D7:0 on P2, A7:0 on P0)
;
; Interrupt Mode Select
; INTR       Val  Description
; ----       ---  -----------
INTR EQU 1  ; 1 = Interrupt pushes 4 bytes onto the stack (PC & PSW1)
;           ; 0 = Interrupt pushes 2 bytes onto the stack (PCL & PCH only)
;
; Extended Data Float (EDF) Timing Feature
; EDF        Val  Description
; ----       ---  -----------
EDF  EQU 1  ; 1 = Standard (Compatibility) Mode
;           ; 0 = extend data float timing for slow memory devices
;
; Wait State for PSEN#/RD#/WR# signal for region 01:xxxx (WSB1 & WSB0 Bits)
; WSB        Val  Description
; ---        ---  -----------
WSB  EQU 3  ; 3 = 0 wait state for region 01:xxxx
;           ; 2 = extended to 1 wait state  for regions 01:xxxx
;           ; 1 = extended to 2 wait states for regions 01:xxxx
;           ; 0 = extended to 3 wait states for regions 01:xxxx
;
; EPROM/ROM Mapping
; WSA        Val  Description
; ---        ---  -----------
EMAP EQU 1 ;  1 = Map internal ROM only to region FF:xxxx
;          ;  0 = Map higher 8KB of internal ROM to region 00:E000 - 00:FFFF
;
;  Note:  the bit SRC is defined with the A251 directive MODSRC/MODBIN
;
;------------------------------------------------------------------------------
;
;  User-defined Power-On Zero Initialization of Memory
;
;  With the following EQU statements the zero initialization of memory
;  at processor reset can be defined:
;
;               ; the absolute start-address of EDATA memory is always 0
EDATALEN        EQU     420H    ; the length of EDATA memory in bytes.
;
XDATASTART      EQU     10000H  ; the absolute start-address of XDATA memory
XDATALEN        EQU     0       ; the length of XDATA memory in bytes.
;
HDATASTART      EQU     10000H  ; the absolute start-address of HDATA memory
HDATALEN        EQU     0       ; the length of HDATA memory in bytes.
;
;  Note:  The EDATA space overlaps physically the DATA, IDATA, BIT and EBIT
;         areas of the 251 CPU.
;
;------------------------------------------------------------------------------
;
;  CPU Stack Size Definition
;
;  The following EQU statement defines the stack space available for the
;  251 application program.  It should be noted that the stack space must
;  be adjusted according the actual requirements of the application.
;
STACKSIZE       EQU     100H    ; set to 100H Bytes.
;
;------------------------------------------------------------------------------
;
;  Reentrant Stack Initialization
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
;
;  Stack Space for reentrant functions in the SMALL model.
IBPSTACK        EQU     0       ; set to 1 if small reentrant is used.
IBPSTACKTOP     EQU     0FFH+1  ; set top of stack to highest location+1.
;
;  Stack Space for reentrant functions in the LARGE model.
XBPSTACK        EQU     0       ; set to 1 if large reentrant is used.
XBPSTACKTOP     EQU     0FFFFH+1; set top of stack to highest location+1.
;
;------------------------------------------------------------------------------

$IF ROMHUGE
Prefix  LIT '?'
Model   LIT 'FAR'
PRSeg   LIT 'ECODE'
$ELSE
Prefix  LIT ''
Model   LIT 'NEAR'
PRSeg   LIT 'CODE'
$ENDIF

$include (reg251s.inc)

EXTRN NUMBER (?C?XDATASEG)              ; Start of XDATA Segment

                NAME    ?C_START{Prefix}


; Setting of the Chip Configuration Bytes
$IF __MODSRC__
SRCM            EQU     1  ; Select Source Mode
$ELSE
SRCM            EQU     0  ; Select Binary Mode
$ENDIF

$IF (CONFIGB)
CONFIG0         EQU     (WSA*20H)+(XALE*10H)+(RDRG*4)+(PAGM*2)+SRCM+080H
CONFIG1         EQU     (INTR*10H)+(EDF*8)+(WSB*2)+EMAP+0E0H

                CSEG    AT      0FFF8H
                DB      CONFIG0         ; Config Byte 0
                DB      CONFIG1         ; Config Byte 1
$ENDIF


?C_C51STARTUP       SEGMENT   ECODE
?C_C51STARTUP?3     SEGMENT   ECODE
?C_C51STARTUP_CODE  SEGMENT   CODE

?STACK          SEGMENT   EDATA

                RSEG    ?STACK
                DS      STACKSIZE       ; Stack Space 100H Bytes

                EXTRN PRSeg (MAIN{Prefix})
                PUBLIC  ?C_STARTUP{Prefix}
                PUBLIC  ?C?STARTUP{Prefix}

                CSEG    AT      0
?C?STARTUP{Prefix}:
?C_STARTUP{Prefix}:
                LJMP    STARTUP1

                RSEG    ?C_C51STARTUP_CODE

STARTUP1:
                EJMP    STARTUP1_ECODE



                RSEG    ?C_C51STARTUP

STARTUP1_ECODE:
                MOV     DPXL,#?C?XDATASEG

IF EDATALEN <> 0
                MOV     WR8,#EDATALEN - 1
                CLR     A
EDATALOOP:      MOV     @WR8,R11
                DEC     WR8,#1
                JNE     EDATALOOP
ENDIF

IF XDATALEN <> 0
                MOV     DPTR,#WORD0 XDATASTART
                MOV     WR6,#XDATALEN
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DEC     WR6,#1
                JNE     XDATALOOP
ENDIF

IF HDATALEN <> 0
                MOV     DR16,#WORD0 HDATALEN
IF (WORD2 HDATALEN) <> 0
                MOV     WR16,#WORD2 HDATALEN
ENDIF
                MOV     WR12,#WORD2 HDATASTART
                MOV     WR14,#WORD0 HDATASTART
                CLR     A
HDATALOOP:      MOV     @DR12,R11
                INC     DR12,#1
                DEC     DR16,#1
                JNE     HDATALOOP
ENDIF

IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)

                MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

                MOV     DR60,#WORD0 (?STACK-1)

                RSEG    ?C_C51STARTUP?3
                JMP     Model MAIN{Prefix}

                END

INITEDAT.A51

This file is required if you have variables in EDATA that must be initialized.

;----------------------------------------------------------------------------
;
; Init records for EDATA (near) memory.  The record structure is as follows:
;
;    Byte 0  Byte 1  Byte 2  Byte 3  Byte 4
;   +-------+-------+-------+-------+-------+
;   |Len MSB|Len LSB|Adr MSB|Adr LSB|Content|
;   +-------+-------+-------+-------+-------+
;   |                               +Rep Len+
;   +--- Repeated for each Object ----------+
;
; The complete EDATA initialization is placed into the segment ?C_INITEDATA
; (segment class is HCONST).
;
;----------------------------------------------------------------------------

                NAME    ?C?INITEDATA
PUBLIC          ?C?INITEDATA
PUBLIC          ?C?INITEDATA?ECODE
EXTRN HCONST (?C?INITEDATA_END)

?C_INITEDATA            SEGMENT   HCONST         ; Segment with init tables (records)
?C_C51STARTUP?2         SEGMENT   ECODE          ; Code for table driven Init
?C_C51STARTUP_CODE      SEGMENT   CODE

                RSEG    ?C_C51STARTUP_CODE
?C?INITEDATA:

                RSEG    ?C_C51STARTUP?2
?C?INITEDATA?ECODE:
                MOV     WR0,#WORD2 ?C_INITEDATA
                MOV     WR2,#WORD0 ?C_INITEDATA
INIT_LOOP:      MOV     WR8,@DR0        ; WR8 contains Length
                ANL     WR8,WR8
                JE      INIT_END
                MOV     WR4,@DR0+2      ; WR4 contains Address
                INC     DR0,#4
                INC     WR8,#1
                SJMP    INIT_OBJ1
INIT_OBJ0:      MOV     R11,@DR0
                MOV     @WR4,R11
                INC     WR4,#1
                INC     DR0,#1
INIT_OBJ1:      DEC     WR8,#1
                JNE     INIT_OBJ0
                SJMP    INIT_LOOP
INIT_END:

                END

INITHDAT.A51

This file is required if you have variables in HDATA that must be initialized.

;----------------------------------------------------------------------------
;
; Init records for HDATA (near) memory.  The record structure is as follows:
;
;    Byte 0  Byte 1  Byte 2  Byte 3  Byte 4  Byte 5
;   +-------+-------+-------+-------+-------+-------+
;   |Len MSB|Len LSB|Adr MSB|Adr Mid|Adr LSB|Content|
;   +-------+-------+-------+-------+-------+-------+
;   |                                       +Rep Len+
;   +--- Repeated for each Object ------------------+
;
; The complete HDATA initialization is placed into the segment ?C_INITHDATA
; (segment class is HCONST).
;
;----------------------------------------------------------------------------

                NAME    ?C?INITHDATA
PUBLIC          ?C?INITHDATA
PUBLIC          ?C?INITHDATA?ECODE
EXTRN HCONST (?C?INITHDATA_END)

?C_INITHDATA            SEGMENT   HCONST        ; Segment with init tables (records)
?C_C51STARTUP?2         SEGMENT   ECODE         ; Code for table driven Init
?C_C51STARTUP_CODE      SEGMENT   CODE

                RSEG    ?C_C51STARTUP_CODE
?C?INITHDATA:

                RSEG    ?C_C51STARTUP?2
?C?INITHDATA?ECODE:
                MOV     WR0,#WORD2 ?C_INITHDATA
                MOV     WR2,#WORD0 ?C_INITHDATA
INIT_LOOP:      MOV     WR8,@DR0        ; WR8 contains Length
                ANL     WR8,WR8
                JE      INIT_END
                MOV     R5,@DR0+2
                MOVZ    WR4,R5
                MOV     WR6,@DR0+3      ; DR4 contains Address
                ADD     DR0,#5
                INC     WR8,#1
                SJMP    INIT_OBJ1
INIT_OBJ0:      MOV     R11,@DR0
                MOV     @DR4,R11
                INC     DR4,#1
                INC     DR0,#1
INIT_OBJ1:      DEC     WR8,#1
                JNE     INIT_OBJ0
                SJMP    INIT_LOOP
INIT_END:

                END

ATTACHED FILES

Request the files attached to this knowledgebase article.

Article last edited on: 2005-08-03 15:45:49

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential