You've already forked ultrasm64-2
mirror of
https://github.com/HackerN64/ultrasm64-2.git
synced 2026-01-21 10:38:08 -08:00
@@ -392,9 +392,6 @@ s32 D_SH_80343CF0;
|
||||
s8 D_SH_80343CF8_pad[0x8];
|
||||
struct UnkStruct80343D00 D_SH_80343D00;
|
||||
s8 D_SH_8034DC8_pad[0x8];
|
||||
#ifndef LIBULTRA_EXCLUSIVE
|
||||
ALIGNED8 OSPiHandle DriveRomHandle; // used in osDriveRomInit.c. Why here?
|
||||
#endif
|
||||
s8 D_SH_80343E48_pad[0x8];
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
#include "sm64.h"
|
||||
|
||||
#if defined(TARGET_N64) && (defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN))
|
||||
#include "PR/os_internal.h"
|
||||
#include "lib/ultra/libc/xstdio.h"
|
||||
#include "lib/hackerlibultra/src/libc/xstdio.h"
|
||||
|
||||
u8 gCrashScreenCharToGlyph[128] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
@@ -113,16 +112,12 @@ void crash_screen_print(s32 x, s32 y, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
size = _Printf(write_to_buf, buf, fmt, args);
|
||||
size = _Printf((void*)write_to_buf, buf, fmt, args);
|
||||
|
||||
if (size > 0) {
|
||||
ptr = buf;
|
||||
|
||||
#if defined(VERSION_SH) || defined(VERSION_CN)
|
||||
while (size > 0) {
|
||||
#else
|
||||
while (*ptr) {
|
||||
#endif
|
||||
|
||||
glyph = gCrashScreenCharToGlyph[*ptr & 0x7f];
|
||||
|
||||
@@ -130,9 +125,7 @@ void crash_screen_print(s32 x, s32 y, const char *fmt, ...) {
|
||||
crash_screen_draw_glyph(x, y, glyph);
|
||||
}
|
||||
|
||||
#if defined(VERSION_SH) || defined(VERSION_CN)
|
||||
size--;
|
||||
#endif
|
||||
|
||||
ptr++;
|
||||
x += 6;
|
||||
@@ -189,16 +182,11 @@ void draw_crash_screen(OSThread *thread) {
|
||||
cause = 17;
|
||||
}
|
||||
|
||||
#if defined(VERSION_SH) || defined(VERSION_CN)
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
|
||||
crash_screen_draw_rect(25, 20, 270, 25);
|
||||
crash_screen_print(30, 25, "THREAD:%d (%s)", thread->id, gCauseDesc[cause]);
|
||||
crash_screen_print(30, 35, "PC:%08XH SR:%08XH VA:%08XH", tc->pc, tc->sr, tc->badvaddr);
|
||||
#ifdef VERSION_EU
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
crash_screen_sleep(2000);
|
||||
crash_screen_draw_rect(25, 45, 270, 185);
|
||||
crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0,
|
||||
@@ -221,9 +209,6 @@ void draw_crash_screen(OSThread *thread) {
|
||||
(u32) tc->sp);
|
||||
crash_screen_print(30, 140, "S8:%08XH RA:%08XH", (u32) tc->s8, (u32) tc->ra);
|
||||
crash_screen_print_fpcsr(tc->fpcsr);
|
||||
#ifdef VERSION_EU
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
crash_screen_print_float_reg(30, 170, 0, &tc->fp0.f.f_even);
|
||||
crash_screen_print_float_reg(120, 170, 2, &tc->fp2.f.f_even);
|
||||
crash_screen_print_float_reg(210, 170, 4, &tc->fp4.f.f_even);
|
||||
@@ -240,9 +225,6 @@ void draw_crash_screen(OSThread *thread) {
|
||||
crash_screen_print_float_reg(120, 210, 26, &tc->fp26.f.f_even);
|
||||
crash_screen_print_float_reg(210, 210, 28, &tc->fp28.f.f_even);
|
||||
crash_screen_print_float_reg(30, 220, 30, &tc->fp30.f.f_even);
|
||||
#ifdef VERSION_EU
|
||||
osWritebackDCacheAll();
|
||||
#endif
|
||||
osViBlack(FALSE);
|
||||
osViSwapBuffer(gCrashScreen.framebuffer);
|
||||
}
|
||||
@@ -277,38 +259,20 @@ void thread2_crash_screen(UNUSED void *arg) {
|
||||
}
|
||||
|
||||
void crash_screen_set_framebuffer(u16 *framebuffer, u16 width, u16 height) {
|
||||
#ifdef VERSION_EU
|
||||
gCrashScreen.framebuffer = framebuffer;
|
||||
#else
|
||||
gCrashScreen.framebuffer = (u16 *)((uintptr_t)framebuffer | 0xa0000000);
|
||||
#endif
|
||||
gCrashScreen.width = width;
|
||||
gCrashScreen.height = height;
|
||||
}
|
||||
|
||||
void crash_screen_init(void) {
|
||||
#ifdef VERSION_EU
|
||||
gCrashScreen.framebuffer = (u16 *) (osMemSize | 0x80000000) - SCREEN_WIDTH * SCREEN_HEIGHT;
|
||||
#else
|
||||
gCrashScreen.framebuffer = (u16 *) (osMemSize | 0xA0000000) - SCREEN_WIDTH * SCREEN_HEIGHT;
|
||||
#endif
|
||||
gCrashScreen.width = SCREEN_WIDTH;
|
||||
#ifdef VERSION_EU
|
||||
gCrashScreen.height = SCREEN_HEIGHT;
|
||||
#else
|
||||
gCrashScreen.height = 0x10;
|
||||
#endif
|
||||
osCreateMesgQueue(&gCrashScreen.mesgQueue, &gCrashScreen.mesg, 1);
|
||||
osCreateThread(
|
||||
&gCrashScreen.thread, 2, thread2_crash_screen, NULL,
|
||||
(u8 *) gCrashScreen.stack + sizeof(gCrashScreen.stack),
|
||||
#ifdef VERSION_EU
|
||||
OS_PRIORITY_APPMAX
|
||||
#else
|
||||
OS_PRIORITY_RMON
|
||||
#endif
|
||||
);
|
||||
osStartThread(&gCrashScreen.thread);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
266
src/game/libgcc.c
Normal file
266
src/game/libgcc.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/* --------------------------------------------------------------------------------*/
|
||||
/* Depending on the toolchain used, an appropriate precompiled libgcc library */
|
||||
/* may not exist and cannot be linked against. Until we have a better work around, */
|
||||
/* necessary gcc functions are hosted here in order to properly compile. */
|
||||
/* This file is NOT a part of the original game and only exists to help gcc work. */
|
||||
/* --------------------------------------------------------------------------------*/
|
||||
|
||||
#include <ultra64.h>
|
||||
|
||||
// Self-hosted libc memory functions, gcc assumes these exist even in a freestanding
|
||||
// environment and there is no way to tell it otherwise.
|
||||
|
||||
void *memset(void *dest, int val, size_t len) {
|
||||
unsigned char *ptr = dest;
|
||||
while (len-- > 0)
|
||||
*ptr++ = val;
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const u8 *m1 = s1;
|
||||
const u8 *m2 = s2;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (m1[i] < m2[i]) {
|
||||
return -1;
|
||||
} else if (m1[i] > m2[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t len) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
if (d < s)
|
||||
while (len--)
|
||||
*d++ = *s++;
|
||||
else {
|
||||
char *lasts = (char *) s + (len - 1);
|
||||
char *lastd = (char *) d + (len - 1);
|
||||
while (len--)
|
||||
*lastd-- = *lasts--;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
// Conversions involving 64-bit integer types required by the O32 MIPS ABI.
|
||||
|
||||
// f32 -> u64, negative values become 0
|
||||
u64 __fixunssfdi(f32 a) {
|
||||
if (a > 0.0f) {
|
||||
register union {
|
||||
f64 f;
|
||||
u64 i;
|
||||
} m;
|
||||
|
||||
__asm__("cvt.l.s %0, %1" : "=f"(m.f) : "f"(a));
|
||||
return m.i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// f64 -> u64, negative values become 0
|
||||
u64 __fixunsdfdi(f64 a) {
|
||||
if (a > 0.0) {
|
||||
register union {
|
||||
f64 f;
|
||||
u64 i;
|
||||
} m;
|
||||
|
||||
__asm__("cvt.l.d %0, %1" : "=f"(m.f) : "f"(a));
|
||||
return m.i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// f32 -> s64
|
||||
s64 __fixsfdi(f32 c) {
|
||||
register union {
|
||||
f64 f;
|
||||
s64 i;
|
||||
} m;
|
||||
|
||||
__asm__("cvt.l.s %0, %1" : "=f"(m.f) : "f"(c));
|
||||
return m.i;
|
||||
}
|
||||
|
||||
// f64 -> s64
|
||||
s64 __fixdfdi(f64 c) {
|
||||
register union {
|
||||
f64 f;
|
||||
s64 i;
|
||||
} m;
|
||||
|
||||
__asm__("cvt.l.d %0, %1" : "=f"(m.f) : "f"(c));
|
||||
return m.i;
|
||||
}
|
||||
|
||||
// s64 -> f32
|
||||
f32 __floatdisf(s64 c) {
|
||||
register union {
|
||||
f64 f;
|
||||
s64 i;
|
||||
} m;
|
||||
register f32 v;
|
||||
|
||||
m.i = c;
|
||||
__asm__("cvt.s.l %0, %1" : "=f"(v) : "f"(m.f));
|
||||
return v;
|
||||
}
|
||||
|
||||
// s64 -> f64
|
||||
f64 __floatdidf(s64 c) {
|
||||
register union {
|
||||
f64 f;
|
||||
s64 i;
|
||||
} m;
|
||||
register f64 v;
|
||||
|
||||
m.i = c;
|
||||
__asm__("cvt.d.l %0, %1" : "=f"(v) : "f"(m.f));
|
||||
return v;
|
||||
}
|
||||
|
||||
// u64 -> f32
|
||||
f32 __floatundisf(u64 c) {
|
||||
register union {
|
||||
f64 f;
|
||||
u64 i;
|
||||
} m;
|
||||
register f32 v;
|
||||
|
||||
m.i = c;
|
||||
__asm__("cvt.s.l %0, %1" : "=f"(v) : "f"(m.f));
|
||||
if ((s64) c < 0) {
|
||||
// cvt.s.l assumes signed input, adjust output
|
||||
v += 4294967296.0f; // 2^32
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// u64 -> f64
|
||||
f64 __floatundidf(u64 c) {
|
||||
register union {
|
||||
f64 f;
|
||||
u64 i;
|
||||
} m;
|
||||
register f64 v;
|
||||
|
||||
m.i = c;
|
||||
__asm__("cvt.d.l %0, %1" : "=f"(v) : "f"(m.f));
|
||||
if ((s64) c < 0) {
|
||||
// cvt.d.l assumes signed input, adjust output
|
||||
v += 18446744073709551616.0; // 2^64
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// Compute x^m by binary exponentiation
|
||||
|
||||
f32 __powisf2(f32 x, s32 m) {
|
||||
u32 n = (m < 0) ? -m : m;
|
||||
f32 y = (n % 2 != 0) ? x : 1.0f;
|
||||
|
||||
while (n >>= 1) {
|
||||
x = x * x;
|
||||
|
||||
if (n % 2 != 0) {
|
||||
y = y * x;
|
||||
}
|
||||
}
|
||||
return (m < 0) ? (1.0f / y) : y;
|
||||
}
|
||||
|
||||
int __ucmpdi2(unsigned long long a, unsigned long long b) {
|
||||
if (a == b) {
|
||||
return 1;
|
||||
}
|
||||
return (a < b) ? 0 : 2;
|
||||
}
|
||||
|
||||
// Compute division and modulo of 64-bit signed and unsigned integers
|
||||
|
||||
__asm__(" \n\
|
||||
.set push \n\
|
||||
.set noreorder \n\
|
||||
.set gp=64 \n\
|
||||
\n\
|
||||
.global __umoddi3 \n\
|
||||
__umoddi3: \n\
|
||||
.type __umoddi3, @function \n\
|
||||
.ent __umoddi3 \n\
|
||||
sw $a0, 0x0($sp) \n\
|
||||
sw $a1, 0x4($sp) \n\
|
||||
sw $a2, 0x8($sp) \n\
|
||||
sw $a3, 0xC($sp) \n\
|
||||
ld $t6, 0($sp) \n\
|
||||
ld $t7, 8($sp) \n\
|
||||
dremu $v0, $t6, $t7 \n\
|
||||
dsll32 $v1, $v0, 0 \n\
|
||||
dsra32 $v1, $v1, 0 \n\
|
||||
jr $ra \n\
|
||||
dsra32 $v0, $v0, 0 \n\
|
||||
.end __umoddi3 \n\
|
||||
.size __umoddi3, . - __umoddi3 \n\
|
||||
\n\
|
||||
.global __udivdi3 \n\
|
||||
__udivdi3: \n\
|
||||
.type __udivdi3, @function \n\
|
||||
.ent __udivdi3 \n\
|
||||
sw $a0, 0x0($sp) \n\
|
||||
sw $a1, 0x4($sp) \n\
|
||||
sw $a2, 0x8($sp) \n\
|
||||
sw $a3, 0xC($sp) \n\
|
||||
ld $t6, 0($sp) \n\
|
||||
ld $t7, 8($sp) \n\
|
||||
ddivu $v0, $t6, $t7 \n\
|
||||
dsll32 $v1, $v0, 0 \n\
|
||||
dsra32 $v1, $v1, 0 \n\
|
||||
jr $ra \n\
|
||||
dsra32 $v0, $v0, 0 \n\
|
||||
.end __udivdi3 \n\
|
||||
.size __udivdi3, . - __udivdi3 \n\
|
||||
\n\
|
||||
.global __moddi3 \n\
|
||||
__moddi3: \n\
|
||||
.type __moddi3, @function \n\
|
||||
.ent __moddi3 \n\
|
||||
sw $a0, 0x0($sp) \n\
|
||||
sw $a1, 0x4($sp) \n\
|
||||
sw $a2, 0x8($sp) \n\
|
||||
sw $a3, 0xC($sp) \n\
|
||||
ld $t6, 0($sp) \n\
|
||||
ld $t7, 8($sp) \n\
|
||||
drem $v0, $t6, $t7 \n\
|
||||
dsll32 $v1, $v0, 0 \n\
|
||||
dsra32 $v1, $v1, 0 \n\
|
||||
jr $ra \n\
|
||||
dsra32 $v0, $v0, 0 \n\
|
||||
.end __moddi3 \n\
|
||||
.size __moddi3, . - __moddi3 \n\
|
||||
\n\
|
||||
.global __divdi3 \n\
|
||||
__divdi3: \n\
|
||||
.type __divdi3, @function \n\
|
||||
.ent __divdi3 \n\
|
||||
sw $a0, 0x0($sp) \n\
|
||||
sw $a1, 0x4($sp) \n\
|
||||
sw $a2, 0x8($sp) \n\
|
||||
sw $a3, 0xC($sp) \n\
|
||||
ld $t6, 0($sp) \n\
|
||||
ld $t7, 8($sp) \n\
|
||||
ddiv $v0, $t6, $t7 \n\
|
||||
dsll32 $v1, $v0, 0 \n\
|
||||
dsra32 $v1, $v1, 0 \n\
|
||||
jr $ra \n\
|
||||
dsra32 $v0, $v0, 0 \n\
|
||||
.end __divdi3 \n\
|
||||
.size __divdi3, . - __divdi3 \n\
|
||||
\n\
|
||||
.set pop \n\
|
||||
\n");
|
||||
@@ -130,7 +130,7 @@ void setup_mesg_queues(void) {
|
||||
|
||||
void alloc_pool(void) {
|
||||
void *start = (void *) SEG_POOL_START;
|
||||
void *end = (void *) SEG_POOL_END;
|
||||
void *end = (void *) (SEG_POOL_START + POOL_SIZE);
|
||||
|
||||
main_pool_init(start, end);
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
@@ -329,11 +329,15 @@ void handle_dp_complete(void) {
|
||||
sCurrentDisplaySPTask = NULL;
|
||||
}
|
||||
|
||||
extern void crash_screen_init(void);
|
||||
|
||||
void thread3_main(UNUSED void *arg) {
|
||||
setup_mesg_queues();
|
||||
alloc_pool();
|
||||
load_engine_code_segment();
|
||||
|
||||
crash_screen_init();
|
||||
|
||||
create_thread(&gSoundThread, 4, thread4_sound, NULL, gThread4Stack + 0x2000, 20);
|
||||
osStartThread(&gSoundThread);
|
||||
|
||||
|
||||
@@ -367,8 +367,8 @@ void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd) {
|
||||
}
|
||||
|
||||
void load_engine_code_segment(void) {
|
||||
void *startAddr = (void *) SEG_ENGINE;
|
||||
u32 totalSize = SEG_FRAMEBUFFERS - SEG_ENGINE;
|
||||
void *startAddr = (void *) _engineSegmentStart;
|
||||
u32 totalSize = _engineSegmentEnd - _engineSegmentStart;
|
||||
UNUSED u32 alignedSize = ALIGN16(_engineSegmentRomEnd - _engineSegmentRomStart);
|
||||
|
||||
bzero(startAddr, totalSize);
|
||||
|
||||
Reference in New Issue
Block a user