mirror of
https://github.com/FIX94/hbc.git
synced 2024-11-22 18:49:20 +01:00
208 lines
6.1 KiB
ArmAsm
208 lines
6.1 KiB
ArmAsm
// this file was taken from libogc, see http://www.devkitpro.org/
|
|
|
|
#include "asm.h"
|
|
|
|
#define _SDA_BASE_ 32768
|
|
#define _SDA2_BASE_ 32768
|
|
|
|
|
|
.text
|
|
.section .init
|
|
|
|
# crt0.s file for the GameCube V1.1 by Costis (costis@gbaemu.com)!
|
|
#
|
|
# Updates: Added support for clearing the BSS section so that global
|
|
# variables are cleared to 0 upon start-up.
|
|
#
|
|
# This is start-up code for initializing the GameCube system and hardware
|
|
# before executing the actual user program code. It clears the GPR's,
|
|
# initializes the FPR's, initializes the Data, Code, and L2 caches, clears
|
|
# and initializes SPR's, and disables exceptions (interrupts).
|
|
#
|
|
# Have fun!!! Please e-mail any suggestions or bugs to costis@gbaemu.com.
|
|
|
|
# Entry Point
|
|
|
|
.extern __PSInit
|
|
.extern __SyscallInit
|
|
.extern __CacheInit
|
|
.extern __SystemInit
|
|
.extern __sbss_start, __bss_end
|
|
.extern __bat_config
|
|
.extern _main
|
|
.globl _start, __main
|
|
_start:
|
|
b startup
|
|
.ascii "STUB"
|
|
.ascii "HAXX"
|
|
.long 0
|
|
startup:
|
|
# Disable interrupts first thing
|
|
mfmsr r3
|
|
rlwinm r4,r3,0,17,15
|
|
rlwinm r4,r4,0,26,24
|
|
mtmsr r4
|
|
|
|
# Go into real mode
|
|
isync
|
|
lis r3,real@h
|
|
ori r3,r3,real@l
|
|
clrlwi r3,r3,2
|
|
mtsrr0 r3
|
|
|
|
mfmsr r3
|
|
li r4,0x30
|
|
andc r3,r3,r4
|
|
mtsrr1 r3
|
|
rfi
|
|
|
|
real:
|
|
# Set up the BATs the way we like them
|
|
// HID0 = 00110c64:
|
|
// bus checkstops off, sleep modes off,
|
|
// caches off, caches invalidate,
|
|
// store gathering off, enable data cache
|
|
// flush assist, enable branch target cache,
|
|
// enable branch history table
|
|
lis 3,0x0011 ; ori 3,3,0x0c64 ; mtspr 1008,3 ; isync
|
|
|
|
// MSR = 00002000 (FP on)
|
|
li 4,0x2000 ; mtmsr 4
|
|
|
|
// HID0 |= 0000c000 (caches on)
|
|
ori 3,3,0xc000 ; mtspr 1008,3 ; isync
|
|
|
|
// clear all BATs
|
|
li 0,0
|
|
mtspr 528,0 ; mtspr 530,0 ; mtspr 532,0 ; mtspr 534,0 // IBATU 0..3
|
|
mtspr 536,0 ; mtspr 538,0 ; mtspr 540,0 ; mtspr 542,0 // DBATU 0..3
|
|
mtspr 560,0 ; mtspr 562,0 ; mtspr 564,0 ; mtspr 566,0 // IBATU 4..7
|
|
mtspr 568,0 ; mtspr 570,0 ; mtspr 572,0 ; mtspr 574,0 // DBATU 4..7
|
|
isync
|
|
|
|
// clear all SRs
|
|
lis 0,0x8000
|
|
mtsr 0,0 ; mtsr 1,0 ; mtsr 2,0 ; mtsr 3,0
|
|
mtsr 4,0 ; mtsr 5,0 ; mtsr 6,0 ; mtsr 7,0
|
|
mtsr 8,0 ; mtsr 9,0 ; mtsr 10,0 ; mtsr 11,0
|
|
mtsr 12,0 ; mtsr 13,0 ; mtsr 14,0 ; mtsr 15,0
|
|
isync
|
|
|
|
// set [DI]BAT0 for 256MB@80000000,
|
|
// real 00000000, WIMG=0000, R/W
|
|
li 3,2 ; lis 4,0x8000 ; ori 4,4,0x1fff
|
|
mtspr IBAT0L,3 ; mtspr IBAT0U,4 ; mtspr DBAT0L,3 ; mtspr DBAT0U,4 ; isync
|
|
|
|
// set [DI]BAT4 for 256MB@90000000,
|
|
// real 10000000, WIMG=0000, R/W
|
|
addis 3,3,0x1000 ; addis 4,4,0x1000
|
|
mtspr IBAT4L,3 ; mtspr IBAT4U,4 ; mtspr DBAT4L,3 ; mtspr DBAT4U,4 ; isync
|
|
|
|
// set DBAT1 for 256MB@c0000000,
|
|
// real 00000000, WIMG=0101, R/W
|
|
li 3,0x2a ; lis 4,0xc000 ; ori 4,4,0x1fff
|
|
mtspr DBAT1L,3 ; mtspr DBAT1U,4 ; isync
|
|
|
|
// set DBAT5 for 256MB@d0000000,
|
|
// real 10000000, WIMG=0101, R/W
|
|
addis 3,3,0x1000 ; addis 4,4,0x1000
|
|
mtspr DBAT5L,3 ; mtspr DBAT5U,4 ; isync
|
|
|
|
// enable [DI]BAT4-7 in HID4
|
|
lis 3, 0x8200
|
|
mtspr 1011,3
|
|
|
|
// set MSR[DR:IR] = 11, jump to _start
|
|
lis 3,virtual@h ; ori 3,3, virtual@l ; mtsrr0 3
|
|
|
|
mfmsr 3 ; ori 3,3,0x30 ; mtsrr1 3
|
|
rfi
|
|
|
|
virtual:
|
|
|
|
bl InitGPRS # Initialize the General Purpose Registers
|
|
bl __CacheInit # Initialize the system caches
|
|
bl __SyscallInit # Initialize the System Call handler
|
|
bl __SystemInit # Initialize more cache aspects, clear a few SPR's, and disable interrupts.
|
|
|
|
# Clear the BSS section!
|
|
lis r3,__sbss_start@h
|
|
ori r3,r3,__sbss_start@l
|
|
li r4,0
|
|
lis r5,__bss_end@h
|
|
ori r5,r5,__bss_end@l
|
|
sub r5,r5,r3
|
|
bl _memset
|
|
|
|
bl _main # Branch to the user code!
|
|
|
|
eloop:
|
|
b eloop # If the main function returns, which should never happen then just loop endlessly.
|
|
|
|
InitGPRS:
|
|
# Clear all of the GPR's to 0
|
|
li r0,0
|
|
li r3,0
|
|
li r4,0
|
|
li r5,0
|
|
li r6,0
|
|
li r7,0
|
|
li r8,0
|
|
li r9,0
|
|
li r10,0
|
|
li r11,0
|
|
li r12,0
|
|
li r14,0
|
|
li r15,0
|
|
li r16,0
|
|
li r17,0
|
|
li r18,0
|
|
li r19,0
|
|
li r20,0
|
|
li r21,0
|
|
li r22,0
|
|
li r23,0
|
|
li r24,0
|
|
li r25,0
|
|
li r26,0
|
|
li r27,0
|
|
li r28,0
|
|
li r29,0
|
|
li r30,0
|
|
li r31,0
|
|
|
|
lis sp,__crt0stack@h # we take 0x8173FFF0 as the topmost starting point for our stack,this gives us ~128Kb Stack
|
|
ori sp,sp,__crt0stack@l
|
|
addi sp,sp,-4
|
|
stw r0,0(sp)
|
|
stwu sp,-56(sp)
|
|
|
|
lis r2,_SDA2_BASE_@h
|
|
ori r2,r2,_SDA2_BASE_@l # Set the Small Data 2 (Read Only) base register.
|
|
lis r13,_SDA_BASE_@h
|
|
ori r13,r13,_SDA_BASE_@l # Set the Small Data (Read\Write) base register.
|
|
blr
|
|
|
|
//r3 = ptr, r4 = fill, r5 = size
|
|
.globl _memset
|
|
_memset:
|
|
clrlwi. r6,r5,29
|
|
srwi r5,r5,2
|
|
subi r3,r3,4
|
|
mtctr r5
|
|
1: stwu r4,4(r3)
|
|
bdnz 1b
|
|
cmplwi r6,0
|
|
beq 3f
|
|
2: stbu r4,1(r3)
|
|
addic. r6,r6,-1
|
|
bne+ 2b
|
|
3: blr
|
|
|
|
.section .bss
|
|
.balign 8
|
|
__crt0stack_end:
|
|
.space 0x8000
|
|
__crt0stack:
|
|
|