95 lines
No EOL
1.6 KiB
C++
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
|