You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Improved WiiVC check to avoid false positives & added functions to read and manipulate fcr31 (#669)
* Added functions to access and manipulate the fcr31 register * Improved WiiVC emulator check to avoid false positives * Updated comments * Moved float.h to include directory
This commit is contained in:
69
asm/fcr31.s
Normal file
69
asm/fcr31.s
Normal file
@@ -0,0 +1,69 @@
|
||||
.include "macros.inc"
|
||||
.section .text, "ax"
|
||||
.set noreorder
|
||||
.set noat
|
||||
|
||||
glabel fcr_get_rounding_mode
|
||||
cfc1 $v0, $31
|
||||
jr $ra
|
||||
andi $v0, 0x3
|
||||
|
||||
glabel fcr_set_rounding_mode
|
||||
cfc1 $t0, $31
|
||||
xor $at, $t0, $a0
|
||||
andi $at, $at, 0x3
|
||||
xor $at, $at, $t0
|
||||
jr $ra
|
||||
ctc1 $at, $31
|
||||
|
||||
glabel fcr_get_enabled_exceptions
|
||||
cfc1 $v0, $31
|
||||
srl $v0, $v0, 7
|
||||
jr $ra
|
||||
andi $v0, $v0, 0x1f
|
||||
|
||||
glabel fcr_set_enabled_exceptions
|
||||
cfc1 $t0, $31
|
||||
sll $a0, $a0, 7
|
||||
xor $at, $t0, $a0
|
||||
andi $at, $at, 0xf80
|
||||
xor $at, $at, $t0
|
||||
jr $ra
|
||||
ctc1 $at, $31
|
||||
|
||||
glabel fcr_enable_exceptions
|
||||
cfc1 $at, $31
|
||||
andi $a0, $a0, 0x1f
|
||||
sll $a0, $a0, 7
|
||||
or $at, $at, $a0
|
||||
jr $ra
|
||||
ctc1 $at, $31
|
||||
|
||||
glabel fcr_disable_exceptions
|
||||
cfc1 $at, $31
|
||||
andi $a0, $a0, 0x1f
|
||||
sll $a0, $a0, 7
|
||||
or $at, $at, $a0
|
||||
subu $at, $at, $a0
|
||||
jr $ra
|
||||
ctc1 $at, $31
|
||||
|
||||
glabel fcr_get_cause
|
||||
cfc1 $v0, $31
|
||||
srl $v0, $v0, 12
|
||||
jr $ra
|
||||
andi $v0, $v0, 0x3f
|
||||
|
||||
glabel fcr_get_flags
|
||||
cfc1 $v0, $31
|
||||
srl $v0, $v0, 2
|
||||
jr $ra
|
||||
andi $v0, $v0, 0x1f
|
||||
|
||||
glabel fcr_clear_flags
|
||||
cfc1 $t0, $31
|
||||
xor $at, $t0, $0
|
||||
andi $at, $at, 0x7c
|
||||
xor $at, $at, $t0
|
||||
jr $ra
|
||||
ctc1 $at, $31
|
||||
58
include/float.h
Normal file
58
include/float.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef GAME_FLOAT_H
|
||||
#define GAME_FLOAT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef enum {
|
||||
FRC_RM_ROUND_TO_NEAREST = 0x0,
|
||||
FRC_RM_ROUND_TO_ZERO = 0x1,
|
||||
FRC_RM_ROUND_TO_POSITIVE_INFINITY = 0x2,
|
||||
FRC_RM_ROUND_TO_MINUS_INFINITY = 0x3
|
||||
} FloatRoundingMode;
|
||||
|
||||
typedef enum {
|
||||
FRC_EXCEPTION_INEXACT_OPERATION = 0x1,
|
||||
FRC_EXCEPTION_UNDERFLOW = 0x2,
|
||||
FRC_EXCEPTION_OVERFLOW = 0x4,
|
||||
FRC_EXCEPTION_DIVISION_BY_ZERO = 0x8,
|
||||
FRC_EXCEPTION_INVALID_OPERATION = 0x10,
|
||||
FRC_EXCEPTION_UNIMPLEMENTED_OPERATION = 0x20 // only for Cause bits
|
||||
} FloatExceptionBits;
|
||||
|
||||
extern FloatRoundingMode fcr_get_rounding_mode(void);
|
||||
extern void fcr_set_rounding_mode(FloatRoundingMode);
|
||||
|
||||
// Get the Enable bits in FCR31
|
||||
extern FloatExceptionBits fcr_get_enabled_exceptions(void);
|
||||
|
||||
// Set the Enable bits in FCR31 to the given bitset
|
||||
// NOTE: Ares is currently the only emulator to actually respect the Enable bits.
|
||||
// Floating point exceptions will still not occur on other emulators.
|
||||
extern void fcr_set_enabled_exceptions(FloatExceptionBits);
|
||||
|
||||
// Set the Enable bits to 1 for the given exception(s). Do not change any other exceptions.
|
||||
// NOTE: Ares is currently the only emulator to actually respect the Enable bits.
|
||||
// Floating point exceptions will still not occur on other emulators.
|
||||
extern void fcr_enable_exceptions(FloatExceptionBits);
|
||||
|
||||
// Set the Enable bits to 0 for the given exception(s). Do not change any other exceptions.
|
||||
extern void fcr_disable_exceptions(FloatExceptionBits);
|
||||
|
||||
// Returns TRUE if all of the given exceptions are enabled
|
||||
inline Bool32 fcr_check_exceptions_enabled(FloatExceptionBits exceptions) {
|
||||
return (fcr_get_enabled_exceptions() & exceptions) == exceptions;
|
||||
}
|
||||
|
||||
// Gets the exception(s) raised by the most recently executed floating point instruction
|
||||
extern FloatExceptionBits fcr_get_cause(void);
|
||||
|
||||
// Gets the current exception flags. These flags are set when an exception would be raised,
|
||||
// but the exception is not currently enabled. They are only cleared by calling fcr_clear_flags.
|
||||
// NOTE: This currently will only work on console and Ares. Other emulators will always return 0
|
||||
extern FloatExceptionBits fcr_get_flags(void);
|
||||
|
||||
// Clear the current exception flags
|
||||
extern void fcr_clear_flags(void);
|
||||
|
||||
#endif
|
||||
|
||||
1
sm64.ld
1
sm64.ld
@@ -162,6 +162,7 @@ SECTIONS
|
||||
#endif
|
||||
KEEP(BUILD_DIR/asm/pj64_get_count_factor_asm.o(.text*));
|
||||
KEEP(BUILD_DIR/asm/round.o(.text*));
|
||||
KEEP(BUILD_DIR/asm/fcr31.o(.text*));
|
||||
|
||||
BUILD_DIR/src/boot*.o(.text*);
|
||||
BUILD_DIR/src/hvqm*.o(.text*);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <ultra64.h>
|
||||
#include <string.h>
|
||||
#include "emutest_vc.h"
|
||||
#include "float.h"
|
||||
#include "types.h"
|
||||
|
||||
extern OSMesgQueue gSIEventMesgQueue;
|
||||
@@ -90,18 +91,22 @@ void detect_emulator() {
|
||||
}
|
||||
|
||||
/*
|
||||
* This check forces RTZ bug on vc
|
||||
* If console is N64/adequate Emu round-to-nearest (RTN) rounding mode is used
|
||||
* If console is VC round-to-zero (RTZ) mode is used
|
||||
* This check forces RZ bug on vc
|
||||
* If console is N64/adequate Emu, the current rounding mode, which is initialized to round-to-nearest (RN), is used
|
||||
* If console is VC round-to-zero (RZ) mode is always used
|
||||
*
|
||||
* The double value 0.9999999999999999 used is 0x3FEFFFFFFFFFFFFF in binary
|
||||
* Exponent=01111111110, Mantissa=1111111111111111111111111111111111111111111111111111
|
||||
* RTZ will output not 1.0f, RTN will output exactly 1.0f
|
||||
* RZ will output not 1.0f, RN will output exactly 1.0f
|
||||
*/
|
||||
const FloatRoundingMode roundingMode = fcr_get_rounding_mode();
|
||||
fcr_set_rounding_mode(FRC_RM_ROUND_TO_NEAREST);
|
||||
if (1.0f != round_double_to_float(0.9999999999999999)) {
|
||||
gEmulator = EMU_WIIVC;
|
||||
fcr_set_rounding_mode(roundingMode);
|
||||
return;
|
||||
}
|
||||
fcr_set_rounding_mode(roundingMode);
|
||||
|
||||
// Perform a read from unmapped PIF ram.
|
||||
// On console and well behaved emulators, this echos back the lower half of
|
||||
|
||||
Reference in New Issue
Block a user