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

📄 boot.s

📁 ucos 在GAMEBOY上的移植
💻 S
字号:
	IMPORT |Image$$RO$$Base|			; Address of the start of the RO output section.
	IMPORT |Image$$RO$$Limit|			; Address of the first byte beyond the end of the RO output section.
	IMPORT |Image$$RW$$Base|			; Address of the start of the RW output section.
	IMPORT |Image$$RW$$Limit|			; Address of the byte beyond the end of the ZI output section. (The choice of the end of the ZI region rather than the end of the RW region is to maintain compatibility with legacy code.)
	IMPORT |Image$$ZI$$Base|			; Address of the start of the ZI output section.
	IMPORT |Image$$ZI$$Limit|			; Address of the byte beyond the end of the ZI output section.
    IMPORT main    						; THE MAIN ENTRY OF MON PROGRAM


EWRAM_START	EQU	0x02000000				;CPU External Working RAM
EWRAM_END	EQU	0x02040000-1   			;(256 Kbytes)
EWRAM_LEN	EQU	EWRAM_END - EWRAM_START+1

IWRAM_START	EQU	0x03000000				;CPU Internal Working RAM
IWRAM_END	EQU	0x03008000-1			;(32 Kbytes)
IWRAM_LEN	EQU	IWRAM_END - IWRAM_START + 1

EWROM_START	EQU	0x08000000

ARM_USR_SP	EQU	0x03007F00				; GBA USR stack adress
ARM_IRQ_SP	EQU	0x03007FA0				; GBA IRQ stack adress
ARM_SVC_SP	EQU	0x03007FE0				; GBA SVC stack adress

INTR_VECTOR_ADDR	EQU	0x3008000 - 4;


ARM_USE_MODE	EQU	0X10				;	Cpu_Mode_USR	EQU 	0x10
ARM_FIQ_MODE	EQU	0X11
ARM_IRQ_MODE	EQU	0X12    			;	Cpu_Mode_IRQ 	EQU 	0x12
ARM_SVC_MODE	EQU	0X13    			;	Cpu_Mode_SVC 	EQU 	0x13
ARM_ABORT_MODE	EQU	0X17
ARM_UNDEF_MODE	EQU	0X1B
ARM_MODEMASK	EQU	0X1F
ARM_NOINT		EQU	0XC0

	AREA INIT, CODE, READONLY

	ENTRY
_start				; Start Vector
		b	   rom_header_end

Nintendo_Logo
		SPACE 156		; Nintendo Logo Character Data (8000004h)

	; Game Title (80000A0h)
		DCB   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
		DCB   0x00,0x00,0x00,0x00

	;MultiBoot Game Code (80000ACh) 
	;ELSE is all zero
		DCB  "MB  "

	; Maker Code (80000B0h)
		DCB   0x30,0x31
	; Fixed Value (80000B2h)
		DCB   0x96
	; Main Unit Code (80000B3h)
		DCB   0x00
	; Device Type (80000B4h)
		DCB   0x00

	; Unused Data (7Byte) (80000B5h)

		DCB   0x00,0x00,0x00,0x00,0x00,0x00,0x00

	; Software Version No (80000BCh)
		DCB   0x00

	; Complement Check (80000BDh)
		DCB   0xf0

	; Checksum (80000BEh)
		DCB   0x00,0x00

rom_header_end
		b	   start_vector			; This branch must be here for proper
									; positioning of the following header.
									; DO NOT REMOVE IT.

;=====================================================================+
;
; 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
;
;========================================================================+

;==================
;		Reset	  ;
;==================

	EXPORT 	 start_vector
	ALIGN
start_vector
		mov 	r0, #ARM_IRQ_MODE:OR:0x80:OR:0x40 	; Disable interrupts
		msr 	CPSR_c, r0							; Enable IRQ mode
		ldr 	r13, =ARM_IRQ_SP					; Setup IRQ stack pointer

		mov 	r0, #ARM_SVC_MODE:OR:0x80:OR:0x40 	; Disable interrupts
		msr 	CPSR_c, r0							; Enable SVC mode
		ldr 	r13, =ARM_SVC_SP					; Setup SVC stack pointer

; Make sure we are in ExWRAM
		mov     r0,pc								; NOW , we are runing in which space ?
		cmp		r0,#EWROM_START						; is it less then 0x08000000
		bls		SkipEWRAMClear  					; if less , we are runing in a EWRAM
													; if higher, we are runing in a pak ,so no need to do a copy.
; OK, my code is compiler for EWRAM but I run it in a GAMEPAK
; So we need to copy to ExWRAM.
		ldr		r3,=EWRAM_LEN
		ldr		r2,=EWRAM_START
		mov		r6,r2
		ldr		r1,=EWROM_START
		bl		CopyMem			; call CopyMem

; Jump to the ERAM to execute
		bx		r6

SkipEWRAMClear
		ldr 	r0, =|Image$$RO$$Limit| 			; Get pointer to ROM data
		ldr 	r1, =|Image$$RW$$Base| 				; and RAM copy
		ldr 	r3, =|Image$$ZI$$Base| 				; Zero init base => top of initialized data
		cmp 	r0, r1 								; Check that they are different
		beq 	%F1
0 		cmp		r1, r3 								; Copy init data
		ldrcc	r2, [r0], #4
		strcc	r2, [r1], #4
		bcc		%B0
1		ldr 	r1, =|Image$$ZI$$Limit| 			; Top of zero init segment
		mov 	r2, #0
2 		cmp 	r3, r1 								; Zero init
		strcc 	r2, [r3], #4
		bcc		%B2
		
		IMPORT	OSISR
        ldr     r1, =INTR_VECTOR_ADDR				; Set Interrupt Address
        ldr     r0, =OSISR
        str     r0, [r1]

		mov 	r0, #ARM_SVC_MODE:OR:0x40			; Only IRQ enabled
		msr 	CPSR_c, r0

		mov 	r0, #ARM_USE_MODE:OR:0x40
		msr 	CPSR_c, r0							; Switch to USR mode
		ldr 	sp, =ARM_USR_SP					; Setup USR stack pointer


		bl		main		; Now branch to start of C code


		b .
		b	start_vector

;--------ClearMem----------------------+
; Clear memory to 0x00 if length != 0  |
; r0 = Start Address 				   |
; r1 = Length 						   |
;--------------------------------------+
ClearMem
		mov		r2,#3   		; These commands are used in cases where
		add		r1,r1,r2   		; the length is not a multiple of 4,
		bic		r1,r1,r2			; even though it should be.

		mov     r2,#0
		cmp		r1,r2
		beq		ClearMX				; Length is zero so exit

ClrLoop
		stmia   r0!,{r2}
		sub     r1,r1,#4
		cmp		r1,#0
		bne     ClrLoop
ClearMX
		bx      lr				; ret
;---------end of ClearMem------------



;---------- Copy memory --------------+
; r1 = Source Address 				  |
; r2 = Dest Address 				  |
; r3 = Length 						  |
;-------------------------------------+
CopyMem
		mov     r0,#3 		   ; These commands are used in cases where
		add     r3,r3,r0 		; the length is not a multiple of 4,
		bic     r3,r3,r0 		; even though it should be.
		beq     CIDExit 		 ; Length is zero so exit

CIDLoop
		ldmia   r1!,{r0}
		stmia   r2!,{r0}
		sub     r3,r3,#4
	    cmp		r3,#0
		bne     CIDLoop

CIDExit
		bx      lr			; ret
;--------- end of CopyMem ------------------


       ALIGN
       CODE32

;===================================================
;                  Interrupt Processing
;===================================================
    IMPORT     IntrTable

    EXPORT     irq_entry
    ALIGN
    CODE32

irq_entry								; Single interrupts support
        mov     r3, #0x4000000           ; REG_BASE
        ldr     r2, [r3,#0x200]!         ; Read REG_IE
        and     r1, r2, r2, lsr #16      ; r1 = IE & IF
        ldr     r2, =IntrTable

        ands    r0, r1, #1               ; V-Blank Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #2               ; H-Blank Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #4               ; V Counter Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #8               ; Timer 0 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x10            ; Timer 1 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x20            ; Timer 2 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x40            ; Timer 3 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x80            ; Serial Communication Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x100           ; DMA0 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x200           ; DMA1 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x400           ; DMA2 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x800           ; DMA3 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x1000          ; Key Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x2000          ; Cart Interrupt

jump_intr
        strh    r0, [r3, #2]             ; IF Clear
        ldr     r0, [r2]                 ; Jump to user IRQ process
		bx		r0


	END

⌨️ 快捷键说明

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