mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
449 lines
8.7 KiB
C++
449 lines
8.7 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
IceTech GPL Source Code
|
|
Copyright (C) 2026 Justin Marshall
|
|
|
|
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
|
|
|
|
IceTech Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
IceTech Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with IceTech Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "win_local.h"
|
|
|
|
|
|
/*
|
|
==============================================================
|
|
|
|
Clock ticks
|
|
|
|
==============================================================
|
|
*/
|
|
|
|
/*
|
|
================
|
|
Sys_GetClockTicks
|
|
================
|
|
*/
|
|
double Sys_GetClockTicks(void) {
|
|
LARGE_INTEGER li;
|
|
|
|
QueryPerformanceCounter(&li);
|
|
return (double)li.LowPart + (double)0xFFFFFFFF * li.HighPart;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_ClockTicksPerSecond
|
|
================
|
|
*/
|
|
double Sys_ClockTicksPerSecond(void) {
|
|
static double ticks = 0;
|
|
|
|
if (!ticks) {
|
|
HKEY hKey;
|
|
LPBYTE ProcSpeed;
|
|
DWORD buflen, ret;
|
|
|
|
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey)) {
|
|
ProcSpeed = 0;
|
|
buflen = sizeof(ProcSpeed);
|
|
ret = RegQueryValueEx(hKey, "~MHz", NULL, NULL, (LPBYTE)&ProcSpeed, &buflen);
|
|
// If we don't succeed, try some other spellings.
|
|
if (ret != ERROR_SUCCESS) {
|
|
ret = RegQueryValueEx(hKey, "~Mhz", NULL, NULL, (LPBYTE)&ProcSpeed, &buflen);
|
|
}
|
|
if (ret != ERROR_SUCCESS) {
|
|
ret = RegQueryValueEx(hKey, "~mhz", NULL, NULL, (LPBYTE)&ProcSpeed, &buflen);
|
|
}
|
|
RegCloseKey(hKey);
|
|
if (ret == ERROR_SUCCESS) {
|
|
ticks = (double)((unsigned long)ProcSpeed) * 1000000;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ticks;
|
|
}
|
|
|
|
|
|
/*
|
|
==============================================================
|
|
|
|
CPU
|
|
|
|
==============================================================
|
|
*/
|
|
|
|
/*
|
|
================
|
|
HasCPUID
|
|
================
|
|
*/
|
|
static bool HasCPUID(void) {
|
|
return true;
|
|
}
|
|
|
|
#define _REG_EAX 0
|
|
#define _REG_EBX 1
|
|
#define _REG_ECX 2
|
|
#define _REG_EDX 3
|
|
|
|
/*
|
|
================
|
|
CPUID
|
|
================
|
|
*/
|
|
static void CPUID(int func, unsigned regs[4]) {
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
IsAMD
|
|
================
|
|
*/
|
|
static bool IsAMD(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasCMOV
|
|
================
|
|
*/
|
|
static bool HasCMOV(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Has3DNow
|
|
================
|
|
*/
|
|
static bool Has3DNow(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasMMX
|
|
================
|
|
*/
|
|
static bool HasMMX(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasSSE
|
|
================
|
|
*/
|
|
static bool HasSSE(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasSSE2
|
|
================
|
|
*/
|
|
static bool HasSSE2(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasSSE3
|
|
================
|
|
*/
|
|
static bool HasSSE3(void) {
|
|
return false;
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
CPUCount
|
|
|
|
logicalNum is the number of logical CPU per physical CPU
|
|
physicalNum is the total number of physical processor
|
|
returns one of the HT_* flags
|
|
================
|
|
*/
|
|
#define HT_NOT_CAPABLE 0
|
|
#define HT_ENABLED 1
|
|
#define HT_DISABLED 2
|
|
#define HT_SUPPORTED_NOT_ENABLED 3
|
|
#define HT_CANNOT_DETECT 4
|
|
|
|
int CPUCount(int& logicalNum, int& physicalNum) {
|
|
logicalNum = 8;
|
|
physicalNum = 8;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasHTT
|
|
================
|
|
*/
|
|
static bool HasHTT(void) {
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
================
|
|
HasHTT
|
|
================
|
|
*/
|
|
static bool HasDAZ(void) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_GetCPUId
|
|
================
|
|
*/
|
|
cpuid_t Sys_GetCPUId(void) {
|
|
int flags;
|
|
|
|
// verify we're at least a Pentium or 486 with CPUID support
|
|
if (!HasCPUID()) {
|
|
return CPUID_UNSUPPORTED;
|
|
}
|
|
|
|
// check for an AMD
|
|
if (IsAMD()) {
|
|
flags = CPUID_AMD;
|
|
}
|
|
else {
|
|
flags = CPUID_INTEL;
|
|
}
|
|
|
|
// check for Multi Media Extensions
|
|
if (HasMMX()) {
|
|
flags |= CPUID_MMX;
|
|
}
|
|
|
|
// check for 3DNow!
|
|
if (Has3DNow()) {
|
|
flags |= CPUID_3DNOW;
|
|
}
|
|
|
|
// check for Streaming SIMD Extensions
|
|
if (HasSSE()) {
|
|
flags |= CPUID_SSE | CPUID_FTZ;
|
|
}
|
|
|
|
// check for Streaming SIMD Extensions 2
|
|
if (HasSSE2()) {
|
|
flags |= CPUID_SSE2;
|
|
}
|
|
|
|
// check for Streaming SIMD Extensions 3 aka Prescott's New Instructions
|
|
if (HasSSE3()) {
|
|
flags |= CPUID_SSE3;
|
|
}
|
|
|
|
// check for Hyper-Threading Technology
|
|
if (HasHTT()) {
|
|
flags |= CPUID_HTT;
|
|
}
|
|
|
|
// check for Conditional Move (CMOV) and fast floating point comparison (FCOMI) instructions
|
|
if (HasCMOV()) {
|
|
flags |= CPUID_CMOV;
|
|
}
|
|
|
|
// check for Denormals-Are-Zero mode
|
|
if (HasDAZ()) {
|
|
flags |= CPUID_DAZ;
|
|
}
|
|
|
|
return (cpuid_t)flags;
|
|
}
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
FPU
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
typedef struct bitFlag_s {
|
|
char* name;
|
|
int bit;
|
|
} bitFlag_t;
|
|
|
|
static byte fpuState[128], * statePtr = fpuState;
|
|
static char fpuString[2048];
|
|
static bitFlag_t controlWordFlags[] = {
|
|
{ "Invalid operation", 0 },
|
|
{ "Denormalized operand", 1 },
|
|
{ "Divide-by-zero", 2 },
|
|
{ "Numeric overflow", 3 },
|
|
{ "Numeric underflow", 4 },
|
|
{ "Inexact result (precision)", 5 },
|
|
{ "Infinity control", 12 },
|
|
{ "", 0 }
|
|
};
|
|
static char* precisionControlField[] = {
|
|
"Single Precision (24-bits)",
|
|
"Reserved",
|
|
"Double Precision (53-bits)",
|
|
"Double Extended Precision (64-bits)"
|
|
};
|
|
static char* roundingControlField[] = {
|
|
"Round to nearest",
|
|
"Round down",
|
|
"Round up",
|
|
"Round toward zero"
|
|
};
|
|
static bitFlag_t statusWordFlags[] = {
|
|
{ "Invalid operation", 0 },
|
|
{ "Denormalized operand", 1 },
|
|
{ "Divide-by-zero", 2 },
|
|
{ "Numeric overflow", 3 },
|
|
{ "Numeric underflow", 4 },
|
|
{ "Inexact result (precision)", 5 },
|
|
{ "Stack fault", 6 },
|
|
{ "Error summary status", 7 },
|
|
{ "FPU busy", 15 },
|
|
{ "", 0 }
|
|
};
|
|
|
|
/*
|
|
===============
|
|
Sys_FPU_PrintStateFlags
|
|
===============
|
|
*/
|
|
int Sys_FPU_PrintStateFlags(char* ptr, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse) {
|
|
int i, length = 0;
|
|
|
|
length += sprintf(ptr + length, "CTRL = %08x\n"
|
|
"STAT = %08x\n"
|
|
"TAGS = %08x\n"
|
|
"INOF = %08x\n"
|
|
"INSE = %08x\n"
|
|
"OPOF = %08x\n"
|
|
"OPSE = %08x\n"
|
|
"\n",
|
|
ctrl, stat, tags, inof, inse, opof, opse);
|
|
|
|
length += sprintf(ptr + length, "Control Word:\n");
|
|
for (i = 0; controlWordFlags[i].name[0]; i++) {
|
|
length += sprintf(ptr + length, " %-30s = %s\n", controlWordFlags[i].name, (ctrl & (1 << controlWordFlags[i].bit)) ? "true" : "false");
|
|
}
|
|
length += sprintf(ptr + length, " %-30s = %s\n", "Precision control", precisionControlField[(ctrl >> 8) & 3]);
|
|
length += sprintf(ptr + length, " %-30s = %s\n", "Rounding control", roundingControlField[(ctrl >> 10) & 3]);
|
|
|
|
length += sprintf(ptr + length, "Status Word:\n");
|
|
for (i = 0; statusWordFlags[i].name[0]; i++) {
|
|
ptr += sprintf(ptr + length, " %-30s = %s\n", statusWordFlags[i].name, (stat & (1 << statusWordFlags[i].bit)) ? "true" : "false");
|
|
}
|
|
length += sprintf(ptr + length, " %-30s = %d%d%d%d\n", "Condition code", (stat >> 8) & 1, (stat >> 9) & 1, (stat >> 10) & 1, (stat >> 14) & 1);
|
|
length += sprintf(ptr + length, " %-30s = %d\n", "Top of stack pointer", (stat >> 11) & 7);
|
|
|
|
return length;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_FPU_StackIsEmpty
|
|
===============
|
|
*/
|
|
bool Sys_FPU_StackIsEmpty(void) {
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_FPU_ClearStack
|
|
===============
|
|
*/
|
|
void Sys_FPU_ClearStack(void) {
|
|
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_FPU_GetState
|
|
|
|
gets the FPU state without changing the state
|
|
===============
|
|
*/
|
|
const char* Sys_FPU_GetState(void) {
|
|
return "";
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_FPU_EnableExceptions
|
|
===============
|
|
*/
|
|
void Sys_FPU_EnableExceptions(int exceptions) {
|
|
|
|
}
|
|
|
|
/*
|
|
===============
|
|
Sys_FPU_SetPrecision
|
|
===============
|
|
*/
|
|
void Sys_FPU_SetPrecision(int precision) {
|
|
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_FPU_SetRounding
|
|
================
|
|
*/
|
|
void Sys_FPU_SetRounding(int rounding) {
|
|
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_FPU_SetDAZ
|
|
================
|
|
*/
|
|
void Sys_FPU_SetDAZ(bool enable) {
|
|
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sys_FPU_SetFTZ
|
|
================
|
|
*/
|
|
void Sys_FPU_SetFTZ(bool enable) {
|
|
|
|
}
|