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

📄 cstartup.asm

📁 Audio output from sound file for MCU.
💻 ASM
字号:
;==============================================================================
; Cyan Technology Ltd
;
; FILE
;  cstartup.asm - Assembler startup for C programs.
;
; DESCRIPTION
;  Defines C segments. Contains initial code called before C is started
;==============================================================================

                   MODULE   cstartup
                  .ALL

;
; C reserves DATA address 0 for the NULL pointer. The value H'DEAD is put in
; here so that it is easier to spot the effect of a NULL pointer during
; debugging. User memory for constants grows upwards from H'0001. The first
; address is given the equate symbol $??LO_ADDR.
;
                  .SEG     C_RESERVED1
                  ORG      0xe000
                  dc       H'DEAD
$??LO_ADDR        EQU      $

;
; DATA addresses H'EFE0-H'EFFF are used for scratchpad RAM in interrupt mode.
; DATA addresses H'EFC0-H'EFDF are used for scratchpad RAM in user mode.
; DATA addresses H'EFB8-H'EFBF are used for register storage in interrupt mode.
; Then follows the interrupt stack, user stack and user heap.
; User memory for variables grows downwards from the end of the user stack.
; This version of cstartup only contains one area of scratchpad RAM
; which constrains users not to write re-entrant re-interruptable
; code.
; The interrupt stack must start at IY-38 to be compatible with the C compiler.
;
                  .SEG     C_RESERVED2
                  ORG      H'EFB8

$??HI_ADDR        DEQU     $
                  ds       8           ; Interrupt register storage

                  ds       32          ; User Scratchpad
IY_SCRATCH        DEQU     $

$?irq_scratchpad? DEQU     $
                  ds       32          ; Interrupt Scratchpad

;
; The registers that control the functional blocks of the eCOG1 are located
; at addresses H'FEA0 to H'FFCF. The C header file <ecog1.h> declares an
; external structure that descibes the registers. This variable is defined
; below.
;
                  .SEG     REGISTERS
                  ORG      H'FEA0
$fd:
$rg               ds       304

;
; C requires the following segments:
;     CONST  - Constants in ROM. For example:
;                 const char c = 'c' ;
;                 printf( "Hello World!" ) ;
;     VAR    - Variables in RAM. These are set to zero by the cstartup code.
;              For example:
;                 int i ;              (in file scope)
;                 static int i ;       (in function scope)
;     INIT   - Initialisd variables in RAM. For example:
;                 int i = 9 ;          (in file scope)
;                 static int i = 9 ;   (in function scope)
;     INITC  - Initialisation data for the INIT segment
;     HEAP   - The heap. Required if malloc() etc. are used.
;     STACK  - The stack. Always required.
;
; The memory allocated to each segment is defined by the value of
; $??<segment_name>_SIZE as set below. These sizes can be set manually or, if
; the appropriate line is tagged with !PACK and the -pack option is specified
; to ECOGCL, ECOGCL will write in the size actually required for the segment.
; The sizes of the STACK and HEAP segments must be set by the user.
;
$??ISTACK_SIZE    =        H'0040
$??STACK_SIZE     =        H'0100
$??HEAP_SIZE      =        H'0080

; ROM segments
$??INITC_SIZE     =        h'0000  ; !PACK
$??CONST_SIZE     =        h'009d  ; !PACK

; RAM segments
$??INIT_SIZE      =        h'0000  ; !PACK
$??VAR_SIZE       =        h'0008  ; !PACK


; -- Locate DATA segments in memory --
;
; Segments are allocated sequentially by the ??ALLOCATE macro. They may be
; set at fixed addresses by setting ADDR prior to calling ??ALLOCATE.
;
??ALLOCATE        MACRO    seg
                  .SEG     &seg
                  ORG      ADDR
$??&seg!_LO       = ADDR
ADDR              = ADDR + $??&seg!_SIZE
$??&seg!_HI       = ADDR-1
                  ENDMAC

; Allocate DATA ROM
ADDR              = $??LO_ADDR
                  ??ALLOCATE INITC
                  ??ALLOCATE CONST

; Allocate DATA RAM
ADDR              = $??HI_ADDR - $??VAR_SIZE - $??INIT_SIZE
ADDR              = ADDR - $??ISTACK_SIZE - $??STACK_SIZE - $??HEAP_SIZE
                  ??ALLOCATE INIT
                  ??ALLOCATE VAR
                  ??ALLOCATE HEAP
                  ??ALLOCATE STACK
                  ??ALLOCATE ISTACK


; -- Memory initialisation macros --
;
; Segments may be initialised by filling with a constant value using the
; ??SEGFILL macro.  Two symbols are passed, the segment name and the value to
; fill with.  A third symbol (the size) is assumed.
;
??SEGFILL         MACRO    seg, value
                  LOCAL    fill_loop
                  IF       $??&seg!_SIZE
                  ld       x, #$??&seg
                  ld       al, #$??&seg!_SIZE
                  ld       ah, &value
&fill_loop:       st       ah, @(0,x)
                  add      x, #1
                  sub      al, #1
                  bne      &fill_loop
                  ENDIF
                  ENDMAC

;
; Segments may be initialised by copying an initialisation segment with
; the ??SEGCOPY macro. Two symbols are passed, the source and destination
; segment names.
;
??SEGCOPY         MACRO    src, dest
                  IF       $??&src!_SIZE NE $??&dest!_SIZE
                  .ERR     "Copy segments different sizes"
                  ENDIF
                  IF       $??&src!_SIZE
                  ld       x, #$??&src
                  ld       y, #$??&dest
                  ld       al, #$??&src!_SIZE
                  bc
                  ENDIF
                  ENDMAC

;
; Fills a block of memory with a value. Three values are passed, the start
; address for the block, the number of addresses to write to and the value
; to be written.
;
??MEMFILL         MACRO    start, length, value
                  LOCAL    fill_loop
                  ld       x, &start
                  ld       al, &length
                  ld       ah, &value
&fill_loop:       st       ah, @(0,x)
                  add      x, #1
                  sub      al, #1
                  bne      &fill_loop
                  ENDMAC


;
; Input argument for main().
;
                  .SEG     CONST
argv              dc       0,0         ; NULL as two-word byte address 


;
; Start of Code.
;
                  .CODE
                  ORG      H'40

$?cstart_code:
        bra $ecog1ConfigMMU    ; configure MMU and Cache Banks

$ecog1ConfigContinue:

;
; Initialise segments. The HEAP and STACK are filled with H'9999 and H'aaaa
; respectively so that their maximum runtime extents can be checked. The
; INIT segment is set from the ROM initialisers in the INITC segment. The non
; initialised RAM segment VAR is set to zero (compiler puts 0 initialised
; variables in these segments as well as uninitialised ones,x).
;
                  ??SEGFILL HEAP, #h'9999
                  ??SEGFILL STACK, #h'AAAA
                  ??SEGFILL ISTACK, #h'BBBB
                  ??SEGCOPY INITC, INIT
                  ??SEGFILL VAR, #h'0

; Set interrupt stack pointer.
                  ld y, #IY_SCRATCH

; Set user mode flag to allow interupts.
                  st flags, @(-1,y)
                  ld al, @(-1,y)
                  or al, #h'10
                  st al, @(-1,y)
                  ld flags, @(-1,y)

; Set usermode stack pointer
                  ld y, #$??STACK_HI

; Call ecog1Config to setup eCOG1 peripherals
; Defined in module produced by configuration compiler
                  bsr $ecog1Config
                
; Call main, setting argc and argv[0] to 0.
                  ld ah, #argv
                  ld al, #0
                  bsr $main

;
; Main may exit by returning or by explicitly calling $exit. In either case
; exit code will be in AL.
;
$exit:
                  brk                   ; Alert the user if in debug mode
                  bra 0                 ; Restart program

;
; This is the minimal interrupt routine. The contents of FLAGS is restored
; as the program counter is restored using rti.
;
$minimal_handler:
                  st flags,@(-33,y)     ; Store Flags
                  st al, @(-34,y)       ; Store AL

                  ld al, @(-33,y)       ; Put Flags into AL
                  or al, #h'0010        ; Set usermode
                  st al, @(-33,y)       ; Store the value to be restored to Flags

                  brk                   ; Alert the user if in debug mode

                  ld al, @(-34,y)       ; Restore AL
                  rti @(-33,y)          ; Restore PC and Flags

;
; The address exception can happen often during development. A handler
; is put here to catch the exception.
;
$address_error:
                  st flags,@(-33,y)     ; Store Flags
                  st al, @(-34,y)       ; Store AL

                  ld al, @(-33,y)       ; Put Flags into AL
                  or al, #h'0010        ; Set usermode
                  st al, @(-33,y)       ; Store the value to be restored to Flags

                  brk                   ; Alert the user if in debug mode

                  ld al, #h'a
                  st al, @h'ff69        ; Clear status in mmu.address_exception

                  ld al, #h'200
                  st al, @h'ff7a        ; Clear status in emi.ctrl_sts

                  ld al, @(-34,y)       ; Restore AL
                  rti @(-33,y)          ; Restore PC and Flags

; End of startup code
$??CSTARTUP_END      EQU      $

                  ENDMOD

⌨️ 快捷键说明

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