⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _cstart.s03

📁 embed in keil
💻 S03
字号:
;---------------------------------------------------------------;
;                                                               ;
;                       CSTARTUP.S03                            ;
;                                                               ;
; This module contains the entire code executed before the C    ;
; "main" function is called.  The code can be tailored to suit  ;
; special hardware needs.  The code is designed to run on any   ;
; processor based on the 8051 architecture.                     ;
;                                                               ;
; Version: 5.20 [IMAF 960603]                                   ;
;
; Revision control system
;       $Revision: 1.16 $
;
;---------------------------------------------------------------;
    NAME    CSTARTUP
    PUBLIC  init_C
   $DEFFN   init_C(0400H,0,0,0,0,0,0,0)

$defmodel.inc                           ; Defines memory model

    EXTERN  ?C_EXIT                     ; Where to go when program is done
    EXTERN  _R                          ; Register bank (0, 8, 16 or 24)
    EXTERN  main                        ; First C function usually
   $DEFFN   main(32768,0,0,0)
    EXTERN  __low_level_init            ; Setup low level things
   $DEFFN   __low_level_init(0,0,0,0)
    EXTERN  exit
   $DEFFN   exit(0,0,0,0)

  IF banked_mode
    EXTERN    ?X_CALL_L18
  ENDIF

    RSEG    B_UDATA
    RSEG    B_CDATA
    RSEG    B_IDATA
    RSEG    D_UDATA
    RSEG    D_CDATA
    RSEG    D_IDATA
    RSEG    I_UDATA
    RSEG    I_CDATA
    RSEG    I_IDATA
    RSEG    P_UDATA
    RSEG    P_CDATA
    RSEG    P_IDATA

  IF      lcall_mode
    RSEG    X_UDATA
    RSEG    X_CDATA
    RSEG    X_IDATA
    RSEG    ECSTR
    RSEG    CCSTR
  ENDIF

;---------------------------------------------------------------;
; The C stack segment. Should be mapped into internal 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    CSTACK

stack_begin:
    DS      80h                     ; Increase if needed

    COMMON  INTVEC                  ; Should be at location zero

;---------------------------------------------------------------;
; C interrupt routines with defined [vectors] will reserve      ;
; space in this area.  So will handlers written in assembler if ;
; they follow the recommended format.                           ;
;---------------------------------------------------------------;

startup:

  IF lcall_mode
    LJMP    init_C
  ELSE
    AJMP    init_C
  ENDIF

    RSEG    RCODE                    ; Should be loaded after INTVEC

init_C:

    MOV     SP,   #stack_begin - 1   ; From low to high addresses
    MOV     DPTR, #SFB (P_IDATA)     ; Initialize high byte of PDATA.
    MOV     P2,    DPH               ;

;----------------------------------------------------------------------
; Call __low_level_init to perform initialization before initializing
; segments and calling main. If the function returns 0 no segment
; initialization should take place.
;
; Link with your own version of __low_level_init to override the 
; default action: to do nothing but return 1.
;----------------------------------------------------------------------

  IF banked_mode
    MOV    A,    #$BYTE3 __low_level_init
    MOV    DPTR, # LWRD(__low_level_init)
    LCALL  ?X_CALL_L18                    ; main()
  ELSE
  IF lcall_mode
    LCALL  __low_level_init
  ELSE
    ACALL  __low_level_init
  ENDIF
  ENDIF

    MOV    A, R4
    ORL    A, R5
    JZ    skip_init

;---------------------------------------------------------------;
;             C variable initialization section                 ;
;             =================================                 ;
;                                                               ;
; If there is no demand that global/static C variables should   ;
; have a defined value at startup (required by ANSI), the       ;
; following section can be removed to conserve code memory      ;
; size.   Note that this part calls functions in the end of     ;
; this file, that also can be removed if initialized values are ;
; not needed.                                                   ;
;                                                               ;
; Systems controlled by a watch-dog may require additional      ;
; code insertions as the initialization can take several        ;
; milliseconds (if there are many variables) to complete.       ;
; These parts are marked with    *** WDG ***                    ;
;---------------------------------------------------------------;

;===============================================================;
; Zero out sections containing variables without explicit       ;
; initializers like in:                                         ;
;                                                               ;
;       int i;                                                  ;
;       xdata double d[10];                                     ;
;===============================================================;

    MOV     R0, #SFE(I_UDATA)
    SJMP    CLEAR_IDATA_2

CLEAR_IDATA:
    MOV     @R0, #0
    DEC     R0

CLEAR_IDATA_2:
    CJNE    R0, #SFB(I_UDATA), CLEAR_IDATA    
    MOV     R0, #SFE(D_UDATA)
    SJMP    CLEAR_DDATA_2

CLEAR_DDATA:
    MOV     @R0, #0
    DEC     R0

CLEAR_DDATA_2:
    CJNE    R0, #SFB(D_UDATA), CLEAR_DDATA    
    MOV     R0, #SFE(B_UDATA)
    SJMP    CLEAR_BDATA_2

CLEAR_BDATA:
    MOV     @R0, #0
    DEC     R0

CLEAR_BDATA_2:
    CJNE    R0, #SFB(B_UDATA), CLEAR_BDATA    
  IF      lcall_mode
    MOV     DPTR, #SFE (X_UDATA)             ; XDATA
    MOV     R6,   DPH
    MOV     R7,   DPL
    MOV     DPTR, #SFB (X_UDATA)

NEXT_X_UDATA:
    LCALL   COMP_R67_DPTR
    JZ      INIT_P_UDATA
    CLR     A
    MOVX    @DPTR, A
    INC     DPTR
    SJMP    NEXT_X_UDATA

INIT_P_UDATA:
    MOV     DPTR, #SFB (P_UDATA) 
    MOV     R0,   DPL
    MOV     DPTR, #SFE (P_UDATA) 
    MOV     R1,   DPL

NEXT_P_UDATA:
    MOV     A, R0
    CLR     C
    SUBB    A, R1
    JNC     INIT_VARS
    MOV     @R0, #0
    INC     R0
    SJMP    NEXT_P_UDATA
  ENDIF

;===============================================================;
; Copy initializers into the proper memory segments for decla-  ;
; rations like:                                                 ;
;                                                               ;
;       int i = 7;                                              ;
;       idata char *cp = "STRING";                              ;
;===============================================================;

INIT_VARS:
    MOV     DPTR, #BDATA_TABLE               ; BDATA
  IF lcall_mode
    LCALL   DI_INIT
  ELSE
    ACALL   DI_INIT
  ENDIF
 
    MOV     DPTR, #DATA_TABLE                ; DATA

  IF lcall_mode
    LCALL   DI_INIT
  ELSE
    ACALL   DI_INIT
  ENDIF

    MOV     DPTR, #IDATA_TABLE               ; IDATA
  IF lcall_mode
    LCALL   DI_INIT
  ELSE
    ACALL   DI_INIT
  ENDIF

    MOV     DPTR, #PDATA_TABLE               ; PDATA

  IF lcall_mode
    LCALL   X_INIT
  ENDIF

  IF lcall_mode
    MOV     DPTR, #XDATA_TABLE               ; XDATA
    LCALL   X_INIT
    MOV     DPTR, #YDATA_TABLE               ; For the -y compiler option
    LCALL   X_INIT
  ENDIF

skip_init:

;---------------------------------------------------------------;
;          C variable initialization section end                ;
;---------------------------------------------------------------;

;---------------------------------------------------------------;
; Activate the (at link-time) selected register bank.           ;
;---------------------------------------------------------------;

    MOV     PSW, #_R

;---------------------------------------------------------------;
; If hardware must be initiated from assembly or if interrupts  ;
; should be on when reaching main, this is the place to insert  ;
; such code.                                                    ;
;---------------------------------------------------------------;

  IF banked_mode
    MOV     A,    #$BYTE3 main
    MOV     DPTR, #LWRD(main)
    LCALL   ?X_CALL_L18             ; main()
  ELSE

  IF lcall_mode
    LCALL   main                    ; main()
  ELSE
    ACALL   main                    ; main()
  ENDIF
  ENDIF

;---------------------------------------------------------------;
; Now when we are ready with our C program (usually 8051 C      ;
; programs are continuous) we must perform a system-dependent   ;
; action.  In this simple case we just stop.                    ;
;---------------------------------------------------------------;
; DO NOT CHANGE NEXT LINE OF CSTARTUP IF YOU WANT TO RUN YOUR   ;
; SOFTWARE WITH THE AID OF THE C-SPY HLL DEBUGGER.  IT CAN      ;
; THOUGH BE REMOVED IF YOUR PROGRAM IS CONTINUOUS (NO EXIT).    ;
; If it is removed the EXTERN ?C_EXIT line should also be re-   ;
; moved to avoid linking of the "exit" module                   ;
;---------------------------------------------------------------;
  IF lcall_mode
    LJMP    exit 
  ELSE
    AJMP    exit 
  ENDIF

;---------------------------------------------------------------;
; Last part of the C variable initializer code.                 ;
;---------------------------------------------------------------;
  IF lcall_mode

COMP_R67_DPTR:
;===========================;
;       *** WDG ***         ;
;                           ;
; ACC, B, R0-R3 may be used ;
;===========================;
    MOV     A, R7
    XRL     A, DPL
    JNZ     NOT_EQUAL
    MOV     A, R6
    XRL     A, DPH
NOT_EQUAL:
    RET
  ENDIF

DI_INIT:
    CLR     A
    MOVC    A,  @A+DPTR
    MOV     R0, A
    MOV     A,  #1
    MOVC    A,  @A+DPTR
    MOV     R1, A
    MOV     A,  #2
    MOVC    A,  @A+DPTR
    MOV     R6, A
    MOV     A,  #3
    MOVC    A,  @A+DPTR
    MOV     DPL,A
    MOV     DPH,R6
MORE_DI_COPY:
;===========================;
;       *** WDG ***         ;
;                           ;
; ACC, B, R2-R6 may be used ;
;===========================;
    MOV     A,  R0
    XRL     A,  R1
    JNZ     $+3
    RET
    CLR     A
    MOVC    A,   @A+DPTR
    MOV     @R0, A
    INC     DPTR
    INC     R0
    SJMP    MORE_DI_COPY

  IF lcall_mode
X_INIT:
    CLR     A
    MOVC    A,   @A+DPTR
    MOV     R4,  A
    MOV     A,   #1
    MOVC    A,   @A+DPTR
    MOV     R5,  A
    MOV     A,   #2
    MOVC    A,   @A+DPTR
    MOV     R6,  A
    MOV     A,   #3
    MOVC    A,   @A+DPTR
    MOV     R7,  A
    MOV     A,   #4
    MOVC    A,   @A+DPTR
    MOV     R0,  A
    MOV     A,   #5
    MOVC    A,   @A+DPTR
    MOV     DPL, A
    MOV     DPH, R0
MORE_X_COPY:
    LCALL   COMP_R67_DPTR
    JNZ     $+3
    RET
    CLR     A
    MOVC    A,     @A+DPTR
    INC     DPTR
    MOV     R0,    DPH
    MOV     R1,    DPL
    MOV     DPH,   R4
    MOV     DPL,   R5
    MOVX    @DPTR, A
    INC     DPTR
    MOV     R4,    DPH
    MOV     R5,    DPL
    MOV     DPH,   R0
    MOV     DPL,   R1
    SJMP    MORE_X_COPY
  ENDIF

BDATA_TABLE:
    DB      SFB (B_IDATA)
    DB      SFE (B_IDATA)
    DW      SFB (B_CDATA)

DATA_TABLE:
    DB      SFB (D_IDATA)
    DB      SFE (D_IDATA)
    DW      SFB (D_CDATA)

IDATA_TABLE:
    DB      SFB (I_IDATA)
    DB      SFE (I_IDATA)
    DW      SFB (I_CDATA)

PDATA_TABLE:
    DW      SFB (P_IDATA)
    DW      SFE (P_CDATA)
    DW      SFB (P_CDATA)

  IF lcall_mode
XDATA_TABLE:
    DW      SFB (X_IDATA)
    DW      SFE (X_CDATA)
    DW      SFB (X_CDATA)
YDATA_TABLE:
    DW      SFB (ECSTR)
    DW      SFE (CCSTR)
    DW      SFB (CCSTR)
  ENDIF

    ENDMOD  startup

;---------------------------------------------------------------;
; Function/module: exit (int code)                              ;
;                                                               ;
; When C-SPY is used this code will automatically be replaced   ;
; by a 'debug' version of exit().                               ;
;---------------------------------------------------------------;
    MODULE  exit

    PUBLIC  exit
   $DEFFN   exit(0,0,0,0,0,0,0,0)
    PUBLIC  ?C_EXIT

    RSEG    RCODE

?C_EXIT:
exit:
;---------------------------------------------------------------;
; The next line could be replaced by user defined code.         ;
;---------------------------------------------------------------;
    SJMP    $               ; Forever... 

    ENDMOD

;----------------------------------------------------------------------
;
; The only action of this default version of __low_level_init is to
; return 1. By doing so it signals that normal initialization of data
; segments should be done.
;
; A customized version of __low_level_init may be created in order to
; perform initialization before initializing segments and calling main
; and/or to skip initialization of data segments under certain 
; circumstances.
; For further details see sample file lowinit.c
;
;----------------------------------------------------------------------

    MODULE  lowinit
    PUBLIC  __low_level_init
   $DEFFN   __low_level_init(0,0,0,0,32768,0,0,0)
    EXTERN  Init_Board    
    RSEG    CODE

__low_level_init:    

    lcall  Init_Board            ;M骴ulo espec韋ico. A.F. 14/3/2001

    MOV    R4, #1                ; By returning 1 this function
    MOV    R5, #0                ; indicates that the normal     
                                 ; initialization should take place
  IF banked_mode
    EXTERN    ?X_RET_L18
    LJMP    ?X_RET_L18    
  ELSE
    RET
  ENDIF

    END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -