spo/simulator_SIC_XE/include/utils.h
2025-11-13 22:44:11 +01:00

95 lines
No EOL
1.6 KiB
C++

#ifndef UTILS_H
#define UTILS_H
#include "constants.h"
#include <cmath>
// ==============================
// SIC/XE Utility Functions
// ==============================
// Instruction bit extraction utilities
inline int getXBit(int b2) {
return (b2 & 0x80) ? 1 : 0;
}
inline int getBPBits(int b2) {
return (b2 >> 5) & 0x03;
}
enum class AddressingMode {
IMMEDIATE,
INDIRECT,
SIMPLE,
SIC_DIRECT,
INVALID
};
// Get addressing mode from ni bits
AddressingMode getAddressingMode(int ni);
// convert to signed 24-bit integer
inline int toSIC24(int value) {
value &= 0xFFFFFF;
if (value & 0x800000) {
value -= 0x1000000;
}
return value;
}
inline int setCC(int sw, int cc) {
sw &= ~CC_MASK;
sw |= (cc & CC_MASK);
return sw;
}
inline int sic_comp(int a, int b, int sw) {
int sa = toSIC24(a);
int sb = toSIC24(b);
int cc;
if (sa < sb) {
cc = CC_LT;
} else if (sa == sb) {
cc = CC_EQ;
} else {
cc = CC_GT;
}
return setCC(sw, cc);
}
inline int sic_comp(double a, double b, int sw) {
int cc;
if (a < b) {
cc = CC_LT;
} else if (a == b) {
cc = CC_EQ;
} else {
cc = CC_GT;
}
return setCC(sw, cc);
}
inline int getCC(int sw) {
return sw & CC_MASK;
}
inline double normaliseFloat(double value)
{
if (value == 0.0 )return 0.0;
if (!std::isfinite(value)) return value;
double mantissa = value;
while (std::fabs(mantissa) >= 10.0) mantissa /= 10.0;
while (std::fabs(mantissa) < 1.0) mantissa *= 10.0;
return mantissa;
}
#endif // UTILS_H