?? boot.s
字號:
;/*
;************************************************************************************************************
;** boot.s **
;************************************************************************************************************
;*/
IMPORT |Image$$RO$$Base| ;// 聲明輸入ROM區中的RO的開始地址
IMPORT |Image$$RO$$Limit| ;// 聲明輸入ROM區中的RW地址(即:存儲RO代碼最后地址的下一地址)
IMPORT |Image$$RW$$Base| ;// 聲明輸入RAM區的開始地址
IMPORT |Image$$RW$$Limit| ;// 聲明輸入零初始化區的開始地址(即:RAM區的最后地址的下一地址)
IMPORT |Image$$ZI$$Base| ;// 聲明輸入零初始化區的開始地址
IMPORT |Image$$ZI$$Limit| ;// 聲明輸入零初始化區的末地址的下一地址
IMPORT main ;// 聲明輸入主程序入口地址
EWRAM_START EQU 0x02000000 ;// CPU外部工作RAM
EWRAM_END EQU 0x02040000-1 ;// (256 Kbytes)
EWRAM_LEN EQU EWRAM_END - EWRAM_START+1
IWRAM_START EQU 0x03000000 ;// CPU內部工作RAM(32K)用于儲存程序和數據
IWRAM_END EQU 0x03008000-1 ;// (32 Kbytes)
IWRAM_LEN EQU IWRAM_END - IWRAM_START + 1
EWROM_START EQU 0x08000000 ;// 卡帶記憶體開始地址
ARM_USR_SP EQU 0x03007F00 ;// 用戶堆棧起始地址
ARM_IRQ_SP EQU 0x03007FA0 ;// 普通中斷堆棧起始地址
ARM_SVC_SP EQU 0x03007FE0 ;// 系統調用堆棧起始地址
INTR_VECTOR_ADDR EQU 0x3008000 - 4 ;// 中斷向量地址 0x3007ffc
;//模式定義
ARM_USE_MODE EQU 0X10
ARM_FIQ_MODE EQU 0X11
ARM_IRQ_MODE EQU 0X12
ARM_SVC_MODE EQU 0X13
ARM_ABORT_MODE EQU 0X17
ARM_UNDEF_MODE EQU 0X1B
ARM_SYS_MODE EQU 0X1F
ARM_NOINT EQU 0XC0
;/*
;************************************************************************************************************
;** 程序開始 **
;************************************************************************************************************
;*/
CODE32
AREA INIT, CODE, READONLY
ENTRY ;// 入口
_start ;// 入口
b rom_header_end ;// 跳過程序區域駐留的一些關于游戲的信息
Nintendo_Logo
SPACE 156 ;// 任天堂圖標字符數據 (8000004h)
;// 游戲標題(80000A0h)
DCB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
DCB 0x00,0x00,0x00,0x00
;// 游戲代碼 (80000ACh)
;// 無則全0
DCB "MB "
;// 制造商代碼 (80000B0h)
DCB 0x30,0x31
;// 固定值 (80000B2h)
DCB 0x96
;// 主單元代碼:
;// 儲存可運行軟件的硬件代碼。 (80000B3h)
DCB 0x00
;// 設備類型 (80000B4h)
DCB 0x00
;// 未使用(固定)的數據 (7Byte) (80000B5h)
DCB 0x00,0x00,0x00,0x00,0x00,0x00,0x00
;// 軟件版本號:
;// 儲存ROM版本號 (80000BCh)
DCB 0x00
;// 補碼檢查 (80000BDh)
DCB 0xf0
;// 校驗和(80000BEh)
DCB 0x00,0x00
rom_header_end
b start_vector ;// 這個標號在這里是適當的
;// 作為下面的開始地址
;// 不要刪除它
;/**********************************************************************
;======================================================================+
;
; The following reserved bytes are used if the code is compiled for
; multiboot mode. It does not hurt anything to leave this header in
; even if the code is not compiled for multiboot. The GBA BIOS will
; auto-patch the first two bytes with 0x03 and 0x01, respectively,
; before running any code if it is executed as multiboot.
;
; The following two bytes are included even for non-multiboot supporting
; builds to guarantee that any generic library code that depends on them
; will still be functional.
;======================================================================+
;***********************************************************************/
EXPORT BOOT_METHOD , SLAVE_NUMBER
BOOT_METHOD
DCB 0 ;// boot method (0=ROM boot, 3=Multiplay boot)
SLAVE_NUMBER
DCB 0 ;// slave # (1=slave#1, 2=slave#2, 3=slave#3)
DCB 0 ; reserved
DCB 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
;//---------end--------------------------------------------------------+
;/*
;************************************************************************************************************
;** 復位 **
;************************************************************************************************************
;*/
EXPORT start_vector ;//輸出復位
EXTERN intr_main ;//聲名輸入intr_main
ALIGN
start_vector
;/*
;************************************************************************************************************
;** 堆棧初始化 **
;************************************************************************************************************
;*/
mov r0, #ARM_IRQ_MODE:OR:0x80:OR:0x40 ;// 關中斷
msr CPSR_c, r0 ;// 進入IRQ模式
ldr r13, =ARM_IRQ_SP ;// 初始化IRQ模式堆棧指針
mov r0, #ARM_SVC_MODE:OR:0x80:OR:0x40 ;// 關中斷
msr CPSR_c, r0 ;// 進入SVC模式
ldr r13, =ARM_SVC_SP ;// 初始化SVC模式堆棧指針
;/*
;************************************************************************************************************
;** 初始化應用程序執行環境 **
;************************************************************************************************************
;*/
;//確保CPU運行在外部工作RAM
mov r0,pc ;// 查詢一下現運行在哪個空間
cmp r0,#EWROM_START ;// 是小于 0x08000000 ?
bls SkipEWRAMClear ;// 如果小于, 已運行在外部工作RAM
;// 如果高于, 運行在 pak ,所以我們需要復制.
;//復制代碼到外部工作RAM
ldr r3,=EWRAM_LEN
ldr r2,=EWRAM_START
mov r6,r2
ldr r1,=EWROM_START
bl CopyMem ;//調用 CopyMem
;//跳轉到外部工作RAM執行
bx r6
SkipEWRAMClear
ldr r0, =|Image$$RO$$Limit| ;//輸入ROM區中的RW地址(即:存儲RO代碼最后地址的下一地址)
ldr r1, =|Image$$RW$$Base| ;//RAM區的開始地址
ldr r3, =|Image$$ZI$$Base| ;//零初始化區的開始地址
cmp r0, r1 ;//比較地址是否相同?
beq %F1
0 cmp r1, r3 ;//復制初始化數據
ldrcc r2, [r0], #4 ;//把ROM區中的RW地址中的數據放入寄存器
strcc r2, [r1], #4 ;//把寄存器中的數據放入RAM區中,放完后,剛好到達ZI區的首地址
bcc %B0
1 ldr r1, =|Image$$ZI$$Limit| ;//零初始化區的末地址的下一地址
mov r2, #0
2 cmp r3, r1 ;//對零初始化區進行零初始化
strcc r2, [r3], #4
bcc %B2
ldr r1, =INTR_VECTOR_ADDR ;//設置中斷地址
ldr r0, =intr_main
str r0, [r1]
mov r0, #ARM_SVC_MODE:OR:0x40 ;//使能IRQ中斷
msr CPSR_c, r0
mov r0, #ARM_USE_MODE:OR:0x40 ;//使能IRQ中斷
msr CPSR_c, r0 ;//進入USE模式
ldr sp, =ARM_USR_SP ;//設置USE模式堆棧指針
;/*
;************************************************************************************************************
;** 呼叫主應用程序 **
;************************************************************************************************************
;*/
bl main ;//進入C代碼
;/*
;************************************************************************************************************
;** 內存操作 **
;************************************************************************************************************
;*/
;/**************************************
;--------ClearMem----------------------+
; 內存清零 |
; r0 = 起始地址 |
; r1 = 長度 |
;--------------------------------------+
;**************************************/
ClearMem
mov r2,#3 ;//確保長度是4的倍數
add r1,r1,r2
bic r1,r1,r2
mov r2,#0
cmp r1,r2
beq ClearMX ;//長度為0退出
ClrLoop
stmia r0!,{r2}
sub r1,r1,#4
cmp r1,#0
bne ClrLoop
ClearMX
bx lr ;// ret
;//---------end of ClearMem------------
;/**************************************
;---------- Copy memory --------------+
; 內存復制 |
; r1 = 源地址 |
; r2 = 目標地址 |
; r3 = 長度 |
;-------------------------------------+
;**************************************/
CopyMem
mov r0,#3 ;//確保長度是4的倍數
add r3,r3,r0
bic r3,r3,r0
beq CIDExit ;//長度為0退出
CIDLoop
ldmia r1!,{r0}
stmia r2!,{r0}
sub r3,r3,#4
cmp r3,#0
bne CIDLoop
CIDExit
bx lr ;// ret
;//--------- end of CopyMem ------------------
END ;//結束boot.s
;/*
;************************************************************************************************************
;** 結束 **
;************************************************************************************************************
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -