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

📄 start.asm

📁 相关富士通单片机实用资料5
💻 ASM
📖 第 1 页 / 共 2 页
字号:

;====================================================================
; Declaration of sections (data, const)
;====================================================================
          .SECTION  DATA,      DATA,   ALIGN=2  ; zero clear area
          .SECTION  INIT,      DATA,   ALIGN=2  ; initialized area
          .SECTION  DIRDATA,   DIR,    ALIGN=2  ; zero clear direct
DIRDATA_S:                                             
          .SECTION  DIRINIT,   DIR,    ALIGN=2  ; initialized dir
#if CONSTDATA == RAMCONST
          .SECTION  CINIT,     DATA,   ALIGN=2  ; initialized const
#endif
          .SECTION  LIBDATA,   DATA,   ALIGN=2  ; zero clear lib area
          .SECTION  LIBINIT,   DATA,   ALIGN=2  ; initialized lib area

          .SECTION  DIRCONST, DIRCONST,ALIGN=2  ; DIRINIT initializers
          .SECTION  DCONST,    CONST,  ALIGN=2  ; DINIT initializers
          .SECTION  CONST,     CONST,  ALIGN=2  ; CINIT initializers
          .SECTION  LIBDCONST, CONST,  ALIGN=2  ; LIBDCONST init val

          .SECTION  DCLEAR,    CONST,  ALIGN=2  ; far zero clear table
          .SECTION  DTRANS,    CONST,  ALIGN=2  ; far copy table

;====================================================================
; Stack area and stack top definition
;====================================================================
               .SECTION  SSTACK, STACK, ALIGN=2
          .RES.H    SSSIZE
SSTACK_TOP:
               .SECTION  USTACK, STACK, ALIGN=2
          .RES.H    USSIZE
USTACK_TOP:

;====================================================================
;   ___  _____   __    ___  _____
;  /       |    /  \  |   \   |                  
;  \___    |   |    | |___/   |   
;      \   |   |----| |  \    |   
;   ___/   |   |    | |   \   |      Begin of actual code section
;====================================================================
          .SECTION  CODE_START, CODE, ALIGN=1
          .IMPORT   _main                    ; user code entrance
#if CLIBINIT == ON
          .IMPORT   __stream_init
          .IMPORT   _exit
          .EXPORT   __exit
#endif          
          .EXPORT   _start

;====================================================================
; "NOT RESET YET" WARNING
;====================================================================
notresetyet:
          NOP  ; read hint below!!!!!!!
; If the debugger stays at the NOP above, the controller has not been
; reset yet. In order to reset all hardware register it is highly re-
; commended to reset the controller.
; However, if no reset vector has been defined on purpose, this dummy
; start address can also be used.
; This mechanism is using the .END instruction at the end of this mo-
; dule. It is not necessary for controller operation but improves 
; security during debugging (mainly emulator debugger).

;====================================================================
; Program start address the reset vector should point here
;====================================================================
_start:
          AND  CCR, #0             ; disable interrups
          MOV  ILM,#7              ; set interrupt level mask to ALL
          MOV  RP,#REGBANK         ; set register bank pointer 

;====================================================================
; Set clock ratio (ignore subclock)
;====================================================================
#if CLOCKSPEED != NOCLOCK
          SETB I:CKSCR:2           ; set main clock
#  if CLOCKSPEED > MAINCLOCK
          MOV  A, I:CKSCR          ; copy clock register
          AND  A, #0xFC            ; set x1 for PLL
#    if CLOCKSPEED == PLLx2
          OR   A, #0x01            ; set x2 for PLL
#    elif CLOCKSPEED == PLLx3
          OR   A, #0x02            ; set x3 for PLL
#    elif CLOCKSPEED == PLLx4
          OR   A, #0x03            ; set x4 for PLL
#    endif
          MOV  I:CKSCR, A          ; write back 
          CLRB I:CKSCR:2           ; enable PLL, PLL is not switched
                                   ; to the MCU yet but after stabi-
                                   ; lizing it switchs on its own to
                                   ; higher speed (see below)
#  endif ; CLOCKSPEED > MAINCLOCK 
#endif ; CLOCKSPEED != NOCLOCK 

;====================================================================
; Set some external bus configuaration
;====================================================================

#if BUSMODE != SINGLE_CHIP         ; ext bus used
          MOV  I:HACR, #ADDR_PINS  ; set used upper address lines
          MOV  I:EPCR, #BUS_SIGNAL ; set used bus signals
          MOV  I:ARSR, #iARSR      ; set auto-wait cycles
#endif 

#if FAMILY == MB90500 || FAMILY == MB90400 ; only these have ROMM

#  if BUSMODE == INTROM_EXTBUS     ; EXTBUS and INTROM/EXTROM
#    if ROMMIRROR == OFF && CONSTDATA == ROMCONST
#      error Mirror function must be ON to mirror internal ROM
#    endif
#  endif

          MOV  I:ROMM, #ROMMIRROR
#endif


;====================================================================
; Copy from initial value areas to reserved data area of near data
;====================================================================
#macro    SEGCOPY DEST, SRC
          MOV  A,#BNKSEC \SRC      ; get bank of source section
          MOV  DTB,A               ; store source bank in DTB
          MOV  A,#BNKSEC \DEST     ; get destination bank
          MOV  ADB,A               ; store dest bank in ADB
          MOVW RW0,#SIZEOF (\DEST) ; get size of dest section
          MOVW A,#\DEST            ; move destination offset to AL
          MOVW A,#\SRC             ; move source offset to AL and
                                   ; move AL (dest offset) to AH
          MOVSI     ADB,DTB        ; copy RW0 bytes src->dest
#endm

          SEGCOPY   INIT, DCONST        ; from DCONST to INIT
          SEGCOPY   DIRINIT, DIRCONST   ; from DIRCONST to DIRINIT
          SEGCOPY   LIBINIT, LIBDCONST  ; from LIBDCONST to LIBINIT
#if CONSTDATA == RAMCONST
          SEGCOPY   CINIT, CONST        ; from CONST to CINIT
#endif

;====================================================================
; Clear uninitialized near data areas to zero
;====================================================================
#macro    SEGZERO SEC                   
          MOV  A,#BNKSEC \SEC      ; get bank of section
          MOV  ADB,A               ; store bank in ADB
          MOVW RW0,#SIZEOF (\SEC)  ; store number of bytes in RW0
          MOVW A,#\SEC             ; move dest offset to AL
          MOVN A,#0                ; move fill value to AL and 
                                   ; move AL (offset) to AH
          FILSI     ADB            ; fill RW0 bytes with AL
#endm

          SEGZERO   DATA           ; clear DATA
          SEGZERO   DIRDATA        ; clear DIRDATA
          SEGZERO   LIBDATA        ; clear LIBDATA

;====================================================================
; Copy initial value of far data areas.
; Each C-module has its own far INIT section. The names are generic.
; DCONST_module contains the initializers for the far data of the one
; module. INIT_module reserves the RAM area, which has to be loaded
; with the data from DCONST_module. ("module" is the name of the *.c
; file) 
; All separated DCONST_module/INIT_module areas are described in 
; DTRANS section by start addresses and length of each far section.
;   0000 1. source address (ROM)
;   0004 1. destination address (RAM)
;   0008 length of sections 1
;   000A 2. source address  (ROM)
;   000E 2. destination address (RAM)
;   0012 length of sections 2
;   0014 3. source address ...
;====================================================================
          MOV  A, #BNKSEC DTRANS   ; get bank of table
          MOV  DTB, A              ; store bank in DTB
          MOVW RW1, #DTRANS        ; get start offset of table
          OR   CCR, #H'20          ; System stack flag set (SSB used)
          BRA  LABEL2              ; branch to loop condition
LABEL1:
          MOVW A, @RW1+6           ; get bank of destination
          MOV  SSB, A              ; save dest bank in SSB
          MOVW A, @RW1+2           ; get source bank
          MOV  ADB, A              ; save source bank in ADB
          MOVW A, @RW1+4           ; move destination addr in AL
          MOVW A, @RW1             ; AL ->AH, src addr -> AL 
          MOVW RW0, @RW1+8         ; number of bytes to copy -> RW0
          MOVSI     SPB, ADB       ; copy data
          MOVN A, #10              ; length of one table entry is 10
          ADDW RW1, A              ; set pointer to next table entry
LABEL2:                             
          MOVW A, RW1              ; get address of next block
          SUBW A, #DTRANS          ; sub address of first block
          CMPW A, #SIZEOF (DTRANS) ; all blocks processed ?
          BNE  LABEL1              ; if not, branch

;====================================================================
; Clear uninitialized far data areas to zero
; Each C-module has its own far DATA section. The names are generic.
; DATA_module contains the reserved area (RAM) to be cleared.
; ("module" is the name of the *.c file) 
; All separated DATA_module areas are described in DCLEAR section by
; start addresses and length of all far section.
;   0000 1. section address (RAM)
;   0004 length of section 1
;   0006 2. section address (RAM)
;   000A length of section 2
;   000C 3. section address (RAM)
;   0010 length of section 3 ...
;====================================================================
          MOV  A, #BNKSEC DCLEAR   ; get bank of table
          MOV  DTB, A              ; store bank in DTB
          MOVW RW1, #DCLEAR        ; get start offset of table
          BRA  LABEL4              ; branch to loop condition
LABEL3:                            
          MOV  A, @RW1+2           ; get section bank
          MOV  ADB, A              ; save section bank in ADB
          MOVW RW0, @RW1+4         ; number of bytes to copy -> RW0
          MOVW A, @RW1             ; move section addr in AL
          MOVN A, #0               ; AL ->AH, init value -> AL 
          FILSI     ADB            ; write 0 to section
          MOVN A, #6               ; length of one table entry is 6
          ADDW RW1, A              ; set pointer to next table entry
LABEL4:
          MOVW A, RW1              ; get address of next block
          SUBW A, #DCLEAR          ; sub address of first block
          CMPW A, #SIZEOF (DCLEAR) ; all blocks processed ?
          BNE  LABEL3              ; if not, branch

;====================================================================
; Prepare stacks and set the default stack type
;====================================================================
#macro SYSSTACKINI
          OR   CCR,#H'20               ; set System stack flag
          MOV  A,#BNKSYM SSTACK_TOP    ; System stack set
          MOV  SSB,A                   
          MOVW A,#SSTACK_TOP
          MOVW SP,A
#endm
#macro USRSTACKINI
          AND  CCR,#H'DF               ; User stack flag set
          MOV  A,#BNKSYM USTACK_TOP    ; User stack set
          MOV  USB,A
          MOVW A,#USTACK_TOP
          MOVW SP,A
#endm
#if STACKUSE == USRSTACK
          SYSSTACKINI
          USRSTACKINI                  ; finally user stack selected
#else
          USRSTACKINI
          SYSSTACKINI                  ; finally system stack selected
#endif

;====================================================================
; Set default data bank and direct page register
;====================================================================
          MOV  A,#BNKSEC DATA          ; User data bank offset
          MOV  DTB,A

          MOV  A,#PAGE DIRDATA_S       ; User direct page
          MOV  DPR,A

;====================================================================
; Wait for PLL to stabilize
;====================================================================

#if CLOCKSPEED > MAINCLOCK && CLOCKWAIT == ON
no_PLL_yet:
          BBS  I:CKSCR:6,no_PLL_yet    ; check MCM and wait for
                                       ; PLL to stabilize
#endif

;====================================================================
; Call lib init function: reload stack afterwards, if AUTO-model
;====================================================================
#if CLIBINIT == ON
#  if MEMMODEL == SMALL || MEMMODEL == COMPACT
          CALL __stream_init       ; initialize library IO
#  else                            ; MEDIUM, LARGE, AUTO
          CALLP __stream_init      ; initialize library IO
#    if MEMMODEL == AUTO          
          RELOAD_SP                ; repair stack since stream_init was
                                   ; possibly left by RET (not RETP)
#    endif  ; AUTO
#  endif  ; MEDIUM, LARGE, AUTO
#endif  ; LIBINI

;====================================================================
; Call C-language main entrance
;====================================================================
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
          CALL _main               ; Start main function
#else                              ; MEDIUM, LARGE, AUTO
          CALLP _main              ; Start main function
                                   ; ignore remaining word on stack, 
                                   ; if main was completed by RET
#endif
#if CLIBINIT == ON
#  if MEMMODEL == SMALL || MEMMODEL == COMPACT
          CALL _exit               
#  else                            ; MEDIUM, LARGE, AUTO
          CALLP _exit              ; ignore remaining word on stack, 
                                   ; if main was completed by RET
#  endif
__exit:
#endif          
end:
          BRA  end                 ; Loop

          .END notresetyet         ; define debugger start address
;====================================================================
; End of startup
;====================================================================

⌨️ 快捷键说明

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